Python—基于多个过滤器搜索文件名的高效方法

Python—基于多个过滤器搜索文件名的高效方法,python,search,Python,Search,我有一小段代码来列出与过滤器字符串匹配的文件名。我试图扩展它以匹配多个过滤器。我有一些工作代码,它采用非常直接的循环方法,但它是缓慢的。。。。基本上为每个过滤器运行os.walk 给定函数(如下所示),是否有一种方法可以同时测试多个过滤器,而不是一次测试一个过滤器?i、 e.我是否可以通过筛选字符串列表来查找\u文件 import os import fnmatch # stolen from http://stackoverflow.com/questions/8625991/use-pyt

我有一小段代码来列出与过滤器字符串匹配的文件名。我试图扩展它以匹配多个过滤器。我有一些工作代码,它采用非常直接的循环方法,但它是缓慢的。。。。基本上为每个过滤器运行
os.walk

给定函数(如下所示),是否有一种方法可以同时测试多个过滤器,而不是一次测试一个过滤器?i、 e.我是否可以通过筛选字符串列表来
查找\u文件

import os
import fnmatch

# stolen from http://stackoverflow.com/questions/8625991/use-python-os-walk-to-identify-a-list-of-files
def find_files(dir_look, filt):
    matches = []
    for root, dirnames, filenames in os.walk(dir_look):
      for filename in fnmatch.filter(filenames, filt):
          matches.append(os.path.join(root, filename))
    return matches

#create empty list to store results
filelist=[]

#some example filters, my real data has about 5000 filters
filts = [r'*60830007*',r'*60910259*',r'*60910299*']

#find files for each filter entry
for filter in filts:
    filelist.append(find_files(r'C:\some directory', filter))
编辑:

我发现了一种非常明显的加速方法,将过滤器列表传递给函数,然后在os.walk中测试每个过滤器

def find_files(dir_look, filters):
    matches = []
    for root, dirnames, filenames in os.walk(dir_look):
        for filt in filters:
            for filename in fnmatch.filter(filenames, filt):
                matches.append(os.path.join(root, filename))
    return matches

这个答案将是关于算法和数据结构,而不是python编程

  • 如果您想针对字符串测试很多模式,那么您应该选择更好的表示结构。我们使用的不是字符数组 (有关python实现,请参见

  • 如果您的某些筛选器具有公共部分(特别是如果它们具有相同的前缀),则应将它们表示为。因此,通过这种方式,您可以同时使用多个模式进行测试。此解决方案会产生构建树的开销,但如果您多次使用相同的筛选器,则这是值得的


  • 检查。它快速而健壮。

    现在,对于每个过滤器,都会执行os.WACK。这很慢。也许最好只读取一次,而不只是在上面运行过滤器?感谢Adam,我以前没有见过后缀树,但将来肯定会使用它们。对于这个问题,我想要一些特定的数字,而不是介于两者之间的数字,即我想要6083007和60910259,但不是介于两者之间的100000个数字。是否仍然值得构建后缀树?是的,(我认为)这是值得的。如果您为长度为n in O(n)-O(nlogn)的文件名构建后缀树时间匹配会快得多,因为您只需要在树中找到包含筛选器的分支,而不需要遍历几乎每个字母。如果筛选器只包含数字,则可以获得更好的运行时间,因为在这种情况下,您只需要构建一个(小得多的)带有文件名的数字部分的后缀树。