42

我在大硬盘上的 python 文件查找中搞乱了。我一直在看 os.walk 和 glob。我通常使用 os.walk,因为我发现它更整洁并且似乎更快(对于通常大小的目录)。

有没有人对它们都有任何经验并且可以说哪个更有效?正如我所说,glob 似乎更慢,但你可以使用通配符等,就像 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 个目录中的一小部分网页缓存进行了研究。任务是计算目录中的文件总数。输出是:

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

如您所见,os.listdir是三个中最快的。并且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 是递归的,它们会做不同的事情。

于 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

我认为即使使用 glob 你仍然必须这样做os.walk,除非你直接知道你的子目录树有多深。

顺便提一句。在glob 文档中它说:

“*、? 和用 [] 表示的字符范围将被正确匹配。这是通过使用 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 回答