'static + Life

運良く生きています

Pythonで指定されたディレクトリ内のファイルを条件付きで表記する

ちょっと考えてしまったのでメモ用に。
実行環境はPython 3.6.3

ファイル構成(rootは省く)

hoge ┳ fuwa.txt
     ┣ foo
     ┃ ┣ spam.txt 
     ┃ ┗ ham.txt 
     ┗ bar 
        ┗ test.txt

ジェネレータの作成

import os

def getTree(root: dir=None):
    for r, _, f in os.walk(root):  #os.walkで親ディレクトリ下のディレクトリ(今回は使わない), ファイルの参照
        if r == root:  #パスが親ディレクトリのパスと同値か判定("\"が含まれないようにする)
            for files in f:
                yield os.path.join(r.replace(root, ""), files)  #親ディレクトリのパスを削除
        else:
            for files in f:
                 yield os.path.join(r.replace(root + "\\", ""), files)

一応動作を確認してみる。(今回はDesktopにhogeフォルダを作成したと仮定)

p = "C:\\Users\\<User>\\Desktop\\hoge"
gen = getTree(p)

for path in gen:
    print(path)

実行結果:

fuwa.txt
bar\test.txt
foo\ham.txt
foo\spam.txt

取り出すファイルに条件をつける

今回はfoo\以外を取り出す。

p = "C:\\Users\\<User>\\Desktop\\hoge"
gen = getTree(p)

for path in gen:
    parsed_path = path.split("\\")  # pathを"\"で区切る
    parsed_path[:] = [p for p in parsed_path if "foo" not in parsed_path[0]]  #parseしたpathの最初にfooがあった場合リストを空にする
    if parsed_path:  # 存在するリストか確認
        print(path)

実行結果:

fuwa.txt
bar\test.txt

数個ぐらいのファイルだったらリストを上手く使ってできるけども大量のファイルが存在する場合大量のメモリを使用するので、ジェネレータを使用したものを利用した。除くファイルや入れたいファイルがある場合、 parsed_path[:] = [p for p in parsed_path if <条件式>] を上手に利用してください。
あと、これ以上にいいやり方あったら教えてください。