web-dev-qa-db-ja.com

Pythonディレクトリツリーをウォークする方法は何ですか?

ファイルやフォルダを割り当てて+ = [item]の部分を実行するのは少しハックだと思います。助言がありますか? Python 3.2を使用しています。

from os import *
from os.path import *

def dir_contents(path):
    contents = listdir(path)
    files = []
    folders = []
    for i, item in enumerate(contents):
        if isfile(contents[i]):
            files += [item]
        Elif isdir(contents[i]):
            folders += [item]
    return files, folders
22
Mike

os.walk 含まれるディレクトリとファイルとともにパスを返す関数。これにより、ソリューションが大幅に短縮されます。

31

確かに

items += [item]

多くの理由で悪いです...

  1. appendメソッドが作成されました正確にそのため(1つの要素をリストの末尾に追加)

  2. あなたはそれを捨てるためだけに1つの要素の一時的なリストを作成しています。 Python(それ以外の場合は間違った言語を使用している)を使用する場合、本来の速度は最初の懸念事項ではありませんが、理由もなく速度を浪費することは適切なことではないようです。

  3. Python言語...の少し非対称性を使用しています... a += bを書き込むリストオブジェクトは、a = a + bを書き込むことと同じではありません。前者がオブジェクトを適切に変更するためです。 、2番目は代わりに新しいリストを割り当てますが、オブジェクトaが他の方法を使用して到達可能な場合、これは別のセマンティクスを持つ可能性があります。特定のコードではこれは当てはまらないようですが、後で問題になる可能性があります他の誰か(または数年後には自分でも同じです)がコードを変更する必要がある場合Pythonにはメソッドextendがあり、特に、リストオブジェクトの最後に別のリストの要素を追加することで、リストオブジェクトをインプレースで変更する場合を処理するために作成されました。

また、他の人が指摘したように、あなたのコードはos.walkがすでに行っていることを実行しようとしているようです...

4
6502
def dir_contents(path):
    files,folders = [],[]
    for p in listdir(path):
        if isfile(p): files.append(p)
        else: folders.append(p)
    return files, folders
3
pylover

サブフォルダー内のすべてのファイルを含むすべてのファイルを再帰的に繰り返したい場合は、これが最善の方法だと思います。

import os

def get_files(input):
    for fd, subfds, fns in os.walk(input):
       for fn in fns:
            yield os.path.join(fd, fn)

## now this will print all full paths

for fn in get_files(fd):
    print(fn)
2
Gijs

組み込みのos.walkとos.path.walkの代わりに、他の場所で提案されたこのコードから派生したものを使用します。

http://code.google.com/p/mylibs/source/browse/lib/Python/MyPyLib/DirectoryStatWalker.py

ここでは再貼り付けしませんが、ディレクトリを再帰的に処理するため、非常に効率的で読みやすくなっています。

2
mikebabcock

Python 3.4なので、新しいモジュールpathlibがあります。すべてのディレクトリとファイルを取得するには、次のようにします:

from pathlib import Path

dirs = [str(item) for item in Path(path).iterdir() if item.is_dir()]
files = [str(item) for item in Path(path).iterdir() if item.is_file()]
1
Radek Lonka

append メソッドを使用してみてください。

0
icktoofay

私はまだこれを広範囲にテストしていませんが、これはos.walkジェネレーター、dirnamesをすべてのファイルパスに結合し、結果のリストをフラット化します。検索パス内の具体的なファイルのまっすぐなリストを提供するため。

import itertools
import os

def find(input_path):
    return itertools.chain(
        *list(
            list(os.path.join(dirname, fname) for fname in files)
            for dirname, _, files in os.walk(input_path)
        )
    )
0
ThorSummoner

同じ情報を探している間に、私はこの質問を見つけました。

http://www.pythoncentral.io/how-to-traverse-a-directory-tree-in-python-guide-to-os-walkで見つけた最小の最も明確なコードをここに投稿しています/ (リンクが腐敗した場合は、URLを投稿するだけではありません)。

このページにはいくつかの役立つ情報があり、他のいくつかの関連ページも示しています。

# Import the os module, for the os.walk function
import os

# Set the directory you want to start from
rootDir = '.'
for dirName, subdirList, fileList in os.walk(rootDir):
    print('Found directory: %s' % dirName)
    for fname in fileList:
        print('\t%s' % fname)
0
Mawg