Python 快到os.walk还是glob?

Python 快到os.walk还是glob?,python,traversal,glob,os.walk,directory-walk,Python,Traversal,Glob,Os.walk,Directory Walk,我正在一个大硬盘上用python进行文件查找。我一直在看os.walk和glob。我通常使用os.walk,因为我发现它更整洁,而且似乎更快(对于通常大小的目录) 有没有人对这两种方法都有经验,能说哪一种更有效?正如我所说,glob看起来比较慢,但是你可以使用通配符等等,就像walk一样,你必须过滤结果。下面是一个查找核心转储的示例 core = re.compile(r"core\.\d*") for root, dirs, files in os.walk("/path/to/dir/")

我正在一个大硬盘上用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)


您可以使用os.walk,但仍可以使用全局样式匹配

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

不确定速度,但很明显,由于os.walk是递归的,它们会做不同的事情。

在测量/分析之前,不要浪费时间进行优化。专注于使您的代码简单且易于维护

例如,在您的代码中预编译RE,这不会给您任何速度提升,因为RE模块具有预编译RE的内部缓存

  • 保持简单
  • 如果速度很慢,那么请配置文件
  • 一旦你确切地知道需要优化什么,做一些调整,并始终记录下来

  • 请注意,与“未优化”代码相比,几年前进行的一些优化可能会使代码运行较慢。这尤其适用于现代基于JIT的语言。

    *,?,用[]表示的字符范围将正确匹配。这是通过使用os.listdir()和fnmatch.fnmatch()函数实现的

    我认为即使使用glob,您仍然必须
    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)
    

    我对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)
    

    对我来说,这听起来像是过早的优化。我浏览了一下源代码(和),发现这两个函数都依赖于
    os.listdir
    os.isdir
    ,所以我的直觉告诉我,不管怎样,你都不会获得太多的收益。(然而,正如下面两个答案中所指出的,
    os.walk
    会在子目录上递归,而
    glob.iglob
    不会,因此进行比较没有意义)。如果您最终遇到了性能问题,请概述几种方法。否则,只需写清楚的代码。OP提到了一个“大磁盘”。而且,代码显然已经很简单了。此外,OP似乎处于优化阶段。因此,用“过早的优化是blabla的根源”(实际上是对Knuth的错误引用)之类的话来抛弃与性能相关的问题是一种瘟疫。-1优化在现实(专业)世界中很重要,在现实(专业)世界中,事情往往是非常大规模的。不要在没有任何合理理由的情况下盲目地放弃优化,过早的优化是愚蠢的。它几乎总是使代码更难维护,有时甚至使其性能更差。我不说是这样,但可能是这样。在这里没有任何意义。胡说这里的优化当然很重要。
    os.walk
    lazy(生成器),而
    glob
    会在内存中创建一个大列表吗?这不会递归地通过文件树运行。
    glob.iglob
    会返回一个生成器、python 2、python 3
    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)