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

Posted

技术标签:

【中文标题】在Python中找到两个给定路径之间的公共文件的有效方法【英文标题】:Efficient Method of finding common files between two given paths in Python 【发布时间】:2019-01-08 13:20:21 【问题描述】:

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

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

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

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

【问题讨论】:

你说的普通文件是什么意思? @RoadRunner 具有相同名称和扩展名的文件 @NaseerMohammad 然后只需使用 . 的键创建一个字典,该值将是一个包含两个文件路径中文件频率的元组。如果频率高于这两种情况,则该文件是常见的。 我猜这会增加复杂性。要将每个文件添加到字典中,必须对其进行迭代!!! 【参考方案1】:

您可以使用生成器表达式将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 complexity 和 O(min(len(n), len(m)),而您的具有 2 个嵌套循环的代码始终采用 O(n^2)

【讨论】:

我认为指出为什么@blhsing 的解决方案更快是有帮助的。在您的问题中,@NaseerMohammad,由于嵌套的for 循环,代码会针对dirpath1 中的每个文件 迭代dirpath2!所以代码对dirpath1 中的每个文件做同样的工作。 @blhsing 的解决方案只对每个目录进行一次迭代。 按照建议添加了解释。谢谢。 @blhsing 谢谢。它工作得更快。您能否详细说明您对答案的解释 @NaseerMohammad 不太确定我的答案的哪些部分需要更多详细说明。如果您不确定 Python 的列表理解/生成器表达式是如何工作的,可以参考list comprehension's documentation 了解更多详细信息。我想我已经在我的回答中解释了其余的逻辑。让我知道您还需要更多解释的具体部分。 @NaseerMohammad 我刚刚使用仅输出常见文件名的解决方案更新了我的答案。希望对您有所帮助。

以上是关于在Python中找到两个给定路径之间的公共文件的有效方法的主要内容,如果未能解决你的问题,请参考以下文章

2021-11-17:最长同值路径。给定一个二叉树,找到最长的路径,这个路径中的每个节点具有相同值。 这条路径可以经过也可以不经过根节点。注意:两个节点之间的路径长度由它们之间的边数表示。力扣687。

使用python返回excel中两个不同文件中两列之间的差异

python代码实现二叉树中最低的公共祖先

给定两个单链表,找到两个链表公共节点

给定两个单链表,找到两个链表公共节点

如何在 PHP 中找到两个字符串之间的最大公共子字符串?