如何通过os.walk和fnmatch提高搜索效率

4
我正在使用os.walkfnmatch过滤器来搜索计算机硬盘驱动器中的所有图像文件。虽然这个方法是有效的,但速度非常慢,需要大约9分钟才能搜索到大约70000张图片。
有没有什么优化代码以提高搜索速度的想法?还有其他建议吗?
顺便说一下,我正在使用Python 2.7.2。
import fnmatch
import os

images = ['*.jpg', '*.jpeg', '*.png', '*.tif', '*.tiff']
matches = []

for root, dirnames, filenames in os.walk("C:\\"):
    for extension in images:
        for filename in fnmatch.filter(filenames, extension):
            matches.append(os.path.join(root, filename))
3个回答

4

我不是那种总是依赖于 re 来解决所有问题的正则表达式疯子,但在我的测试中,这个方法实际上比你的 fnmatch 版本要快两倍左右:

import os
import re

matches = []

img_re = re.compile(r'.+\.(jpg|png|jpeg|tif|tiff)$', re.IGNORECASE)

for root, dirnames, filenames in os.walk(r"C:\windows"):
    matches.extend(os.path.join(root, name) for name in filenames if img_re.match(name))

2

我认为Python看起来很不错。

你可以尝试

for root, dirnames, filenames in os.walk("C:\\"):
    for extension in extensions:
        matches.extend(os.path.join(root, filename) for filename 
                       in fnmatch.filter(filenames, extension))

如果这没有产生差异(我想不会),我认为你的硬盘已经成为了这个过程的瓶颈(记住,硬盘==慢,而你正在遍历并列出系统中每个目录的文件)。

如果硬盘是瓶颈,那么多个dir /s ...语句的结果绝对不应该比Python解决方案快得多。


@Levon:感谢您的注意,我已经编辑了我的答案以修复缩进。 - ChristopheD

2
import os
extns = ('.jpg', '.jpeg', '.png', '.tif', '.tiff')
matches = []
for root, dirnames, fns in os.walk("C:\\"):
    matches.extend(
        os.path.join(root, fn) for fn in fns if fn.lower().endswith(extns)
        )

之前没有注意到endswith可以接受一个元组。对re版本进行了运行,它们非常接近,所以我会建议选择任何一个。 - John Gaines Jr.

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接