在python中递归搜索文件的最快方法是什么?

时间:2018-06-20 12:33:19

标签: python search glob

我需要通过递归搜索来生成文件列表,这些文件的路径包含某个字符串。我目前正在这样做:

for i in iglob(starting_directory+'/**/*', recursive=True):
    if filemask in i.split('\\')[-1]: # ignore directories that contain the filemask
        filelist.append(i) 

这是可行的,但是在爬行大型目录树时,它的速度非常慢(约10分钟)。我们在Windows上,因此无法对unix find命令进行外部调用。我的理解是,glob比os.walk更快。

有更快的方法吗?

1 个答案:

答案 0 :(得分:9)

也许不是您想要的答案,但我认为这些时机很有用。在包含15424个目录的目录上运行,该目录总计102,799个文件(其中3059个是.py文件)。

Python 3.6:

import os
import glob

def walk():
    pys = []
    for p, d, f in os.walk('.'):
        for file in f:
            if file.endswith('.py'):
                pys.append(file)
    return pys

def iglob():
    pys = []
    for file in glob.iglob('**/*', recursive=True):
        if file.endswith('.py'):
            pys.append(file)
    return pys

def iglob2():
    pys = []
    for file in glob.iglob('**/*.py', recursive=True):
        pys.append(file)
    return pys

# I also tried pathlib.Path.glob but it was slow and error prone, sadly

%timeit walk()
3.95 s ± 13 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)

%timeit iglob()
5.01 s ± 19.2 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)

%timeit iglob2()
4.36 s ± 34 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)

在cygwin(4.6.0-1)上使用GNU find(4.6.0)

$ time find . -name '*.py' > /dev/null

real    0m8.827s
user    0m1.482s
sys     0m7.284s

好像os.walk一样好。