【问题标题】:What's the fastest way to recursively search for files in python?在python中递归搜索文件的最快方法是什么?
【发布时间】:2018-11-29 14:20:02
【问题描述】:

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

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 快。

有更快的方法吗?

【问题讨论】:

  • 这是什么版本的python?在PEP 471 之后,glob.iglobos.walk 都被更新为快 2-20 倍。
  • 我正在运行 python 3.6。对于每个人的 SA,您所指的 PEP 是从 2014 年开始的。
  • 是的,但是很多人仍然使用没有这些优势的python 2.7。我用os.walkglob.iglobwalk 运行了一个测试用例,它比iglob 快20%,遍历需要大约5 秒的目录结构。我不认为你会用 python 变得更快。也许试试 cygwin 的 find

标签: python search glob


【解决方案1】:

也许不是您希望的答案,但我认为这些时间安排很有用。在包含 15,424 个目录的目录上运行,总共 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)

编辑:下面是在 WINDOWS 上,在 LINUX 上我发现find 的速度提高了大约 25%

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

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

似乎os.walk 和 Windows 一样好。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-09-07
    • 1970-01-01
    • 2017-10-26
    • 2014-12-09
    • 2018-01-17
    • 2021-06-26
    相关资源
    最近更新 更多