気持ち的にはtreeコマンドのようなことをしてくれるものをpythonでできないかというところでした。

こんな感じのディレクトリ構成で

test_dir_1
├── a_1.txt
├── b_1.txt
├── c_1.txt
└── second_dir
    ├── a_2.txt
    ├── b_2.txt
    ├── c_2.txt
    └── third_dir
        ├── a_3.txt
        ├── b_3.txt
        └── c_3.txt

全ての階層のファイルパスを取得したいとなるとglobだとちょっとしんどい(原理的にできるんかもしれんけど)。

こういう場合はos.walk()の方が良い気がする

globの場合

print(glob.glob('./test_dir_1/*'))

"""
['./test_dir_1/b_1.txt',
 './test_dir_1/a_1.txt',
 './test_dir_1/c_1.txt',
 './test_dir_1/second_dir']
"""

print(glob.glob('./test_dir_1/*/*'))

"""
['./test_dir_1/second_dir/b_2.txt',
 './test_dir_1/second_dir/c_2.txt',
 './test_dir_1/second_dir/a_2.txt',
 './test_dir_1/second_dir/third_dir']
"""

print(glob.glob('./test_dir_1/*/*'))

"""
['./test_dir_1/second_dir/third_dir/b_3.txt',
 './test_dir_1/second_dir/third_dir/c_3.txt',
 './test_dir_1/second_dir/third_dir/a_3.txt']
"""

階層の深さが固定ならこれでもいいですが、深さが動的に変わる場合は再起的に深さを探索したいですよね

そんな場合はos.walk()で階層構造をとった場合の方が楽なことが多いでしょう

for i in os.walk('./test_dir_1'):
    print(i)

"""
('./test_dir_1', ['second_dir'], ['b_1.txt', 'a_1.txt', 'c_1.txt'])
('./test_dir_1/second_dir', ['third_dir'], ['b_2.txt', 'c_2.txt', 'a_2.txt'])
('./test_dir_1/second_dir/third_dir', [], ['b_3.txt', 'c_3.txt', 'a_3.txt'])

"""

こんな感じで

  • 第1引数:現在の階層
  • 第2引数:現在の階層にあるディレクトリ
  • 第3引数:現在の階層にあるファイル

が配列で帰ってきます
これを利用してあげた方が便利そうですね

ちょっと上のコードをいじって、for文の中でこんな変数で受けてあげると使いやすいかも

for current_dir, dirs, files in os.walk('./test_dir_1'):
    print(f"In {current_dir}")
    print(f"   dirs  : {dirs}")
    print(f"   files : {files}")

"""
In ./test_dir_1
   dirs  : ['second_dir']
   files : ['b_1.txt', 'a_1.txt', 'c_1.txt']
In ./test_dir_1/second_dir
   dirs  : ['third_dir']
   files : ['b_2.txt', 'c_2.txt', 'a_2.txt']
In ./test_dir_1/second_dir/third_dir
   dirs  : []
   files : ['b_3.txt', 'c_3.txt', 'a_3.txt']

"""