42

大容量のハードディスクで Python のファイル検索をいじっています。私はos.walkとglobを見てきました。私は通常 os.walk を使用します。これは、(通常のサイズのディレクトリの場合) はるかにきれいで、より高速であるように思われるためです。

誰かが両方の経験を持っていて、どちらがより効率的であるかを言うことができますか? 私が言うように、グロブは遅いようですが、ワイルドカードなどを使用できますが、ウォークと同様に、結果をフィルタリングする必要があります。コア ダンプを検索する例を次に示します。

core = re.compile(r"core\.\d*")
for root, dirs, files in os.walk("/path/to/dir/")
    for file in files:
        if core.search(file):
            path = os.path.join(root,file)
            print "Deleting: " + path
            os.remove(path)

または

for file in iglob("/path/to/dir/core.*")
    print "Deleting: " + file
    os.remove(file)
4

4 に答える 4

42

1000 ディレクトリにある Web ページの小さなキャッシュについて調査しました。タスクは、dirs 内のファイルの総数をカウントすることでした。出力は次のとおりです。

os.listdir: 0.7268s, 1326786 files found
os.walk: 3.6592s, 1326787 files found
glob.glob: 2.0133s, 1326786 files found

ご覧のとおり、os.listdirは 3 つのうちで最も高速です。そして、このタスクglog.globよりもまだ高速です。os.walk

起源:

import os, time, glob

n, t = 0, time.time()
for i in range(1000):
    n += len(os.listdir("./%d" % i))
t = time.time() - t
print "os.listdir: %.4fs, %d files found" % (t, n)

n, t = 0, time.time()
for root, dirs, files in os.walk("./"):
    for file in files:
        n += 1
t = time.time() - t
print "os.walk: %.4fs, %d files found" % (t, n)

n, t = 0, time.time()
for i in range(1000):
    n += len(glob.glob("./%d/*" % i))
t = time.time() - t
print "glob.glob: %.4fs, %d files found" % (t, n)
于 2014-12-19T11:43:28.873 に答える
6

測定/プロファイリングの前に最適化のために時間を無駄にしないでください。コードをシンプルで保守しやすいものにすることに重点を置いてください。

たとえば、コードで RE をプリコンパイルすると、速度が向上しません。これは、re モジュールre._cacheにプリコンパイル済み RE の内部があるためです。

  1. 複雑にしないでおく
  2. 遅い場合は、プロファイルします
  3. 何を最適化する必要があるかを正確に把握したら、微調整を行い、常にそれを文書化します

数年前に行われた一部の最適化により、「最適化されていない」コードと比較してコードの実行が遅くなる可能性があることに注意してください。これは、特に最新の JIT ベースの言語に当てはまります。

于 2012-01-19T18:29:44.180 に答える
2

os.walk を使用し、引き続き glob スタイルのマッチングを使用できます。

for root, dirs, files in os.walk(DIRECTORY):
    for file in files:
        if glob.fnmatch.fnmatch(file, PATTERN):
            print file

速度についてはわかりませんが、明らかに os.walk はrecursiveであるため、異なることを行います。

于 2012-01-19T18:25:39.690 に答える
0

*, ?, and character ranges expressed with [] will be correctly matched. This is done by using the os.listdir() and fnmatch.fnmatch() functions

os.walkサブディレクトリツリーの深さを直接知っていない限り、グロブを使用しても、まだ必要があると思います。

ところで。グロブのドキュメントには次のように書かれています:

"*、?、および [] で表される文字範囲は正しく一致します。これは、os.listdir() および fnmatch.fnmatch() 関数を使用して行われます"

私は単に

for path, subdirs, files in os.walk(path):
        for name in fnmatch.filter(files, search_str):
            shutil.copy(os.path.join(path,name), dest)
于 2014-04-26T04:49:48.283 に答える