Python:查找相同的文件并将它们分组

时间:2014-09-22 22:31:23

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

这是课程作业的一个组成部分,所以如果我不能按照自己的需要深入学习,我会道歉。

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

到目前为止,我有一个使用glob迭代每个文件的程序,我也使用filecmp.cmp(file1,file2)来查找相同的文件。我正在努力的是成功比较最多1000个文件所需的逻辑。我确信有更多的pythonic方法来执行此任务,而不是将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],& #39; D':[D]}

提前感谢您的时间!

1 个答案:

答案 0 :(得分:3)

我建议您计算一个" hash"从每个文件的内容。创建一个字典,其中键是哈希值,值是文件名列表。

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。基本上这部分代码与哈希所有文件的解决方案相同;它只是现在你不需要散列每个文件,只需要具有非唯一长度的文件。