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

时间:2018-08-01 04:26:20

标签: python file operating-system

我已经编写了代码,以找出两个给定文件夹(路径)之间的通用文件,以说明子文件夹的所有级别(如果存在)。

请建议是否有更有效的方法。如果指定了包含许多子文件夹级别的文件夹,则会花费太长时间。

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)

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

findCommonDeep("/home/naseer/Python", "/home/naseer/C")

我知道,如果我存储任何给定路径的所有文件的列表,则可以降低执行速度。但我想那会耗尽内存。请指导我更有效地解决这个问题。

1 个答案:

答案 0 :(得分: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

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

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)))

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

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

这效率更高,因为它利用了Python的集合交集操作,该操作的平均time complexityO(min(len(n), len(m)),而带有2个嵌套循环的代码始终需要O(n^2)