提高Python os.walk + 正则表达式算法的效率

4

我正在使用os.walk来从特定文件夹中选择与正则表达式匹配的文件。

for dirpath, dirs, files in os.walk(str(basedir)):
    files[:] = [f for f in files if re.match(regex, os.path.join(dirpath, f))]
    print dirpath, dirs, files

但是这需要处理基础目录下的所有文件和文件夹,这需要花费很长时间。我正在寻找一种方法,在每个步骤中使用与文件相同的正则表达式来过滤掉不需要的目录。或者只匹配正则表达式的一部分...
例如,在以下结构中:
/data/2013/07/19/file.dat

使用以下正则表达式:

/data/(?P<year>2013)/(?P<month>07)/(?P<day>19)/(?P<filename>.*\.dat)

查找所有 .dat 文件,无需查看例如 /data/2012 等文件夹中的内容。


2
你有实际的问题吗? - Martijn Pieters
1
抱歉,我在编辑过程中提交了。现在已经完成了。 - RogerFC
这个正则表达式中没有任何内容表明不应搜索2012。 - Martijn Pieters
我删除了dirs[:] = [...]部分,因为它只是一个失败测试的副本。我的想法是找到一些类似于文件的过滤器函数来过滤掉dirs,但我没有成功,所以我删除了那部分,不将其作为要求。 - RogerFC
2
听起来更适合使用 glob,例如 for filename in glob.iglob('/data/2013/07/19/*.dat'):,但是我不确定问题是什么。 - Tommi Komulainen
显示剩余9条评论
2个回答

1
如果你只想处理 /data/2013/07/19 目录下的文件,可以从目录 top /data/2013/07/19 开始运行 os.walk()。这与 Tommi Komulainen 的建议类似,但你不需要修改循环代码。

0
我遇到了这个问题(即使没有实际的问题,问题也很明显),因为没有人回答,所以我想即使有些晚可能也会有用。
您需要将原始RE拆分为段,以便在循环内过滤中间目录。 过滤,然后匹配文件。
regex_parts = regex.split("/")
del regex_parts[0]  # Because [0] = "" it's not needed

for base, dirs, files in os.walk(root):
   if len(regex_parts) > 1:
       dirs[:] = [dir for dir in dirs if re.match(regex_parts[0], dir)]
       regex_parts[:] = regex_parts[1:]
       continue

   files[:] = [f for f in files if re.match(regex, os.path.join(dirpath, f))]

由于您正在匹配文件(路径的最后一部分),因此在尽可能过滤掉之前,没有理由进行实际匹配。长度检查是为了避免可能与最后一部分匹配的目录被覆盖。这可能可以更有效地完成,但对我有用(我今天刚遇到类似的问题)。


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