使用os.scandir进行递归目录搜索

时间:2016-05-16 13:19:20

标签: python-3.x recursion

我正在搜索大型目录,将旧存档分类为特定顺序。我嵌入了一个递归调用的函数,当它找到一个文件路径与搜索条件匹配的目录时,它将它添加到' found'字典fdict

预期的结果是,在没有子目录的目录上调用该函数时,它完成时没有任何操作,并向后移动一个级别。

当它运行时,它会卡在它找到的第一个不包含子目录的目录中,只是递归地调用当前目录进行搜索,陷入循环中。

以下是代码摘要,非常感谢对循环原因的任何了解。

def scan(queries, directory):
    fdict = {}
    def search(queries, directory, fdict):
        for entry in os.scandir(directory):
            if entry.is_dir():
                for x in queries:
                    if str(x) in entry.path:
                        fdict[str(x)] = entry.path
                        print("{} found and dicted".format(str(x)))
                    else:
                        search(queries, entry.path, fdict)
            else: pass
    search(queries, directory, fdict)
    return fdict

2 个答案:

答案 0 :(得分:0)

好的,事实证明问题出在for x in queries:声明中。

明显的循环是由糟糕的设计引起的,这意味着在调用else语句之前只有queries列表中的第一个值与entry.path相比,并且在当前条目上调用了搜索函数。

一旦找不到没有子目录的目录,它就会向后退一级并在queries中针对entry.path测试第二个条目。

尽管代码最终会产生所需的结果,但这种方法需要绝对的年龄(在这种情况下queries是一个4000长的值列表!)并且在检查时给出了循环的外观。

如果有人遇到类似的问题,以下是未来参考的更正代码。

def scan(queries, directory):
    fdict = {}
    def search(queries, directory, fdict):
        for entry in os.scandir(directory):
            if entry.is_dir():
                if entry.name in queries:
                    fdict[str(x)] = entry.path
                else:
                    time.sleep(2)
                    search(queries, entry.path, fdict)
            else: pass
    search(queries, directory, fdict)
    return fdict

答案 1 :(得分:0)

整件事可以写成

import os
# let qs be a list of queries [q]
# root be the start dir
for path, dirnames, filenames in os.walk(root):
    for dirname in dirnames:
        full_path = os.path.join(path, dirname) # optional (depends)
        for q in qs:
            if q in full_path:
                # do whatever

os.walk是递归的。您也可以执行一些set操作,以消除for q in qs。评论它是否适合您。