6

潜在的に非常に大きなディレクトリ (任意に大きい)を反復処理する必要があります。私が理解していることから、通常の関数は一致するすべてglob.globのファイル名のリストをメモリに保存しますが、関数はイテレータを使用します。したがって、通常の関数を使用することは問題外です。ディレクトリに多くのファイルが存在する可能性があるためです。glob.iglobglob.glob

My problem is that iglob iterates through the directory in a seemingly random order. I would like it to iterate through the files in alphabetical order. I cannot get a list of all the filenames at once, and just sort them, so I am wondering if there is a way to make iglob iterate through the directory in alphabetical order.

4

2 に答える 2

8

いいえ、そうではありません。ディレクトリのすべての内容をメモリに読み込まなければなりません。オペレーティング システムはファイル名をディレクトリ順に提供し、これらを並べ替える場合は、内容を完全にメモリに読み込む必要があります。

出力を呼び出して、iglob()セットがメモリに収まるほど小さい場合は、一致したファイルの後に結果を並べ替えることができます。sorted()iglob()

for filename in sorted(iglob(path)):

iglob()サブディレクトリに再帰しない場合は、すでに単一のディレクトリのすべてのエントリをリストにロードしていることに注意してください(部分的にfnmatch()は list を返すため)。

于 2012-11-11T22:02:36.147 に答える
2

globモジュールのドキュメントから:

このglobモジュールは、Unix シェルで使用される規則に従って、指定されたパターンに一致するすべてのパス名を見つけます。チルダ展開は行われませんが*?、 、 で表される文字範囲は[]正しく一致します。これはos.listdir()fnmatch.fnmatch()、実際にサブシェルを呼び出すのではなく、 関数と 関数を組み合わせて使用​​することによって行われます。

そして、ドキュメントを見るとos.listdir

os.listdir(パス)

パスで指定されたディレクトリ内のエントリの名前を含むリストを返します。 リストは任意の順序です。特別なエントリ「.」は含まれません。および「..」は、ディレクトリに存在する場合でも。

そのglob.globため、ファイルはアルファベット順に返されません。ドキュメントのどこにも記載されていません。この動作に依存するのはバグです。順序付けされたシーケンスが必要な場合は、結果をソートする必要があります。iglobすべての結果が利用可能ではないため、ソートされた結果を返す方法がないことは容易に想像できます。

メモリが本当に問題である場合は、次の 2 つの選択肢があります。

  1. 「アルファベット順」の要件を削除し、 を使用しますiglob
  2. ある種の「バケット ソート」を使用してデータをソートし、ほとんどのデータをディスクに保存して、RAM にチャンクでロードします (このような手法については、The Art of Computer Programming、Book 3 で説明されています)。このアプローチでは、プログラムが遅くなり、おそらく作成がはるかに難しくなります。しかし、本当にすべてのファイル名を RAM に保持できない場合は、最終的にそれらをディスクに保存する必要があります。
于 2012-11-11T22:04:23.433 に答える