高效的在Python中查找两个给定路径之间的公共文件的方法

Nas*_*mad 8 python operating-system file

我编写了代码来查找两个给定文件夹(路径)之间的公共文件,这些文件夹占所有级别的子文件夹(如果存在).

请建议是否有更有效的方法.如果给出具有多级子文件夹的文件夹,则花费太长时间.

def findCommonDeep(self,path1,path2):
    commonfiles = []

    for (dirpath1, dirname1, filenames1) in os.walk(path1):
        for file in filenames1:
            for (dirpath2, dirname2, filenames2) in os.walk(path2):
                if (file in filenames2 and isfile(join(dirpath2, file))):
                        commonfiles.append(file)

    print(commonfiles)
Run Code Online (Sandbox Code Playgroud)

并使用路径调用此函数,如下所示:

findCommonDeep("/home/naseer/Python", "/home/naseer/C")
Run Code Online (Sandbox Code Playgroud)

据我所知,如果我存储任何给定路径的所有文件的列表,则可以降低执行速度.但我想这会耗尽内存.请指导我更有效地接近这个.

blh*_*ing 8

您可以使用生成器表达式将输出os.walk转换为两个集合,并使用集合交集来有效地标识公共路径.

import os
def findCommonDeep(path1, path2):
    files1 = set(os.path.relpath(os.path.join(root, file), path1) for root, _, files in os.walk(path1) for file in files)
    files2 = set(os.path.relpath(os.path.join(root, file), path2) for root, _, files in os.walk(path2) for file in files)
    return files1 & files2
Run Code Online (Sandbox Code Playgroud)

要减少上面代码中的代码重复,您可以使用另一个列表解析:

import os
def findCommonDeep(path1, path2):
    return set.intersection(*(set(os.path.relpath(os.path.join(root, file), path) for root, _, files in os.walk(path) for file in files) for path in (path1, path2)))
Run Code Online (Sandbox Code Playgroud)

如果您只查找常用文件名而不是常用路径名,则可以将生成器表达式输出改为文件名:

def findCommonDeep(path1, path2):
    return set.intersection(*(set(file for _, _, files in os.walk(path) for file in files) for path in (path1, path2)))
Run Code Online (Sandbox Code Playgroud)

这样更有效,因为它利用了Python的集合交集操作,其平均时间复杂度O(min(len(n), len(m)),而具有2个嵌套循环的代码总是需要O(n^2).