【问题标题】:Python: Finding Identical Files And Grouping ThemPython:查找相同的文件并将它们分组
【发布时间】:2014-09-22 22:31:23
【问题描述】:

这是课堂作业的一个组成部分,所以如果我不能按需要深入,我深表歉意。

总而言之,我需要编写一个 python 函数来分组所有相同的文件(即具有相同内容但文件名不同的文件)。将它们分组的目的是最终创建一个类型为 {string: list} 的字典,其中列表是相同文件的组,而键(字符串)只是按字母顺序排序时组中的第一个条目。我们得到一个文件目录。

到目前为止,我有一个使用 glob 遍历每个文件的程序,并且我还使用 filecmp.cmp(file1,file2) 来查找相同的文件。我正在努力的是成功比较最多 1000 个文件所需的逻辑。我确信有一种更 Python 的方式来完成这项任务,而不是将 file1 与 file2、file1 与 file3 等进行比较。

总之,我知道如何遍历文件列表,并且知道如何在拥有相同文件组后创建字典......我只是有点迷失如何有效地获取文件组文件。

示例实现 有 7 个文件:A、AA、AAA、B、BB、C、D。文件 A、AA 和 AAA 相同,B 和 BB 相同,而 C 和 D 是唯一的。我的最终字典应该是:

{'A': [A, AA, AAA], 'B': [B, BB], 'C': [C], 'D': [D]}

提前感谢您的宝贵时间!

【问题讨论】:

    标签: python python-3.x file-io dictionary


    【解决方案1】:

    我建议您根据每个文件的内容计算“哈希”。制作一个字典,其中键是哈希值,值是文件名列表。

    Python hashlib 模块有多种哈希算法可供您使用。我建议使用 SHA-1 或 MD-5。

    两个不同的文件具有相同的哈希值是非常非常不可能的。如果您想完全确定,可以遍历文件列表并比较实际文件值以确保它们确实相同。

    您可以使用defaultdict 来简化此操作:How does collections.defaultdict work?

    这只是未经测试的伪代码,但请执行以下操作:

    from collections import defaultdict
    import hashlib
    
    h = defaultdict(list)
    
    for filename in list_of_files_in_directory:
        with open(filename, "r") as f:
            data = f.read()
        fhash = hashlib.sha1(data).hexdigest()
        h[fhash].append(filename)
    
    # h now contains a key for each unique file contents hash, and a list of filenames for each key
    

    您的字典可以只使用二进制哈希数据作为键,但使用字符串值更方便。 .hexdigest() 方法函数为您提供一个字符串,将哈希表示为十六进制数字。

    编辑:在评论中,@parchment 建议使用os.stat() 来获取文件大小,并且仅在有多个大小相同的文件时才计算文件哈希。这是加快查找相同文件过程的绝佳方法;如果您只有一个具有特定长度的文件,则您知道它不能与任何其他文件相同。如果文件很大,计算哈希值可能会很慢。

    但我建议先编写简单的散列代码,让它工作,然后如果你有时间尝试重写它以检查文件大小。检查文件大小然后有时还会对文件进行哈希处理的代码会更复杂,因此更难正确处理。

    在我的脑海中,这是我将如何重写以使用文件大小:

    创建一个名为done 的空列表。您将在此处存储输出(内容相同的文件名列表)。

    制作一个将文件长度映射到文件名列表的字典。如上所示,您可以使用defaultdict

    遍历字典。每个值都是包含单个文件名的列表,只需将该值附加到 done 列表;唯一长度意味着唯一的文件。每个值是两个或多个文件的列表,您现在需要计算哈希并构建另一个字典,将哈希映射到具有该哈希的文件列表。完成后,只需遍历此字典中的所有值并将它们添加到done。基本上,这部分与散列所有文件的解决方案的代码相同;只是现在您不需要对每个文件进行哈希处理,只需对具有非唯一长度的文件进行哈希处理即可。

    【讨论】:

    • 您可以先通过调用 stat 比较文件大小,然后对相同大小的文件进行哈希处理,以提高性能。散列 1000 个文件可能需要一段时间。
    猜你喜欢
    • 1970-01-01
    • 2019-06-16
    • 2013-10-01
    • 2011-08-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-06-12
    相关资源
    最近更新 更多