pur*_*doo 1 python file-io dictionary python-3.x
这是课堂作业的一个组成部分,因此如果我无法按照需要深入探讨,我深表歉意。
总而言之,我需要编写一个 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],'D':[D]}
在此先感谢您的时间!
我建议您根据每个文件的内容计算“哈希”。创建一个字典,其中键是哈希值,值是文件名列表。
Pythonhashlib模块有多种可以使用的哈希算法。我建议使用 SHA-1 或 MD-5。
两个不相同的文件具有相同哈希值的可能性非常非常小。如果您想绝对确定,您可以循环遍历文件列表并比较实际的文件值以确保它们确实相同。
您可以使用defaultdict使这变得更容易: Collections.defaultdict Difference with normal dict
这只是未经测试的伪代码,但请执行以下操作:
from collections import defaultdict
import hashlib
h = defaultdict(list)
for filename in list_of_files_in_directory:
with open(filename, "rb") 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
Run Code Online (Sandbox Code Playgroud)
您的字典可以仅使用二进制哈希数据作为键,但使用字符串值更方便。该.hexdigest()方法函数为您提供一个以十六进制数字表示哈希值的字符串。
编辑:在评论中,@parchment 建议使用os.stat()来获取文件大小,并且仅在存在多个具有相同大小的文件时才计算文件哈希。这是加快查找相同文件过程的绝佳方法;如果您只有一个具有特定长度的文件,您就知道它不能与任何其他文件相同。如果文件很大,计算哈希值可能会很慢。
但我建议先编写简单的哈希代码,然后让它工作,然后如果有时间尝试重写它以检查文件大小。检查文件大小,有时还对文件进行哈希处理的代码将更加复杂,因此更难以正确执行。
在我的脑海中,以下是我将如何重写以使用文件大小:
创建一个名为 的空列表done。这是您存储输出的位置(内容相同的文件名列表)。
创建一个字典将文件长度映射到文件名列表。您可以defaultdict按照上图所示使用。
循环字典。每个值都是包含单个文件名的列表,只需将该值附加到done列表中即可;唯一的长度意味着唯一的文件。每个值都是两个或多个文件的列表,您现在需要计算哈希值并构建另一个字典,将哈希值映射到具有该哈希值的文件列表。完成后,只需循环该字典中的所有值并将它们添加到done. 基本上这部分与散列所有文件的解决方案的代码相同;只是现在您不需要对每个文件进行哈希处理,只需对长度不唯一的文件进行哈希处理即可。
编辑 2023-11-24:将文件打开为“rb”以避免编码错误。
| 归档时间: |
|
| 查看次数: |
736 次 |
| 最近记录: |