高效准确的方式压缩和比较Python列表?
我正在尝试对两个CSV文件中的每一行进行比较,想找出哪些行在一个文件中出现而在另一个文件中没有。问题是这两个文件中的行的顺序是完全不确定的。作为起点,我尝试比较行的字符串表示形式的哈希值(也就是Python中的列表)。例如:
import csv
hashes = []
for row in csv.reader(open('old.csv','rb')):
hashes.append( hash(str(row)) )
for row in csv.reader(open('new.csv','rb')):
if hash(str(row)) not in hashes:
print 'Not found'
但是这个方法完全失败了。我受到了一些人为设定的内存限制,无法更改,所以我选择了使用哈希值,而不是直接存储和比较列表。因为我比较的某些文件可能有几百兆字节大。有没有什么办法可以准确地压缩Python列表,以便能简单地和其他列表进行比较?也就是说,找一个真正有效的哈希系统?额外加分:为什么上面的方法不行?
编辑:
感谢大家的建议!让我澄清一下。“惨败”是指两个行的数据完全相同,但在用CSV.reader
读取后,调用str
函数得到的哈希值却不一样。我会尝试下面的一些建议中的hashlib
。我也不能对原始文件进行哈希,因为下面的两行包含相同的数据,但行中的字符不同:
1, 2.3, David S, Monday
1, 2.3, "David S", Monday
我已经在做一些字符串处理,以使数据更统一,但似乎没有效果。我并不想要一个非常复杂的比较逻辑,比如说0
和0.0
是一样的。
编辑 2:
问题解决了。基本上,我需要做更多的预处理,比如转换整数和浮点数等等并且我需要更改我的哈希函数。这两个改变似乎解决了我的问题。
7 个回答
要更好地理解“失败得很惨”具体指的是什么,我们需要更多的信息。如果你只是没有正确地比较这两个东西,或许可以试试Hashlib这个库,它可能会帮到你。
我之前在使用内置的哈希库时遇到过麻烦,后来用这个库解决了问题。
补充一下:有网友在其他帖子里提到,问题可能出在你认为这两个文件的每一行必须完全一样。你可以尝试先解析一下csv文件中的字段,然后把它们格式化成相同的字符串(比如去掉空格、全部小写等),再计算哈希值。
由于CSV的语法定义比较松散,可能会出现两行数据在意义上是相同的,但在字面上却不同的情况。各种方言定义给我们提供了一些线索,说明两行数据可以各自格式正确,但却无法直接比较。而这个例子展示了它们可能在同一种方言下,但字符串内容却不相等:
0, 0
0, 0.0
提供更多信息可以帮助我们更好地回答你的问题。
要给出一个好的答案,首先需要了解你的具体情况,不过如果你能为每个文件的每一行存储一个哈希值,那应该没问题。至少,你需要能存储一个文件的哈希列表,然后把它排序并写入磁盘,这样你就可以同时处理两个排序后的列表了。
我能想到的唯一可能导致上述方法不奏效的原因是你的哈希函数对同一个输入不总是返回相同的结果。你可以测试一下,重新处理 old.csv 文件时是否生成相同的哈希列表。这可能和多余的空格、用制表符代替空格、大小写不同等因素有关。
需要注意的是,即使哈希值相同,你也不能确定这些行是完全匹配的;你只能说它们可能匹配。你仍然需要检查候选行是否真的匹配。(有时候,输入文件中可能会有多行生成相同的哈希值,所以你也需要处理这种情况。)
在你填充完 hashes
变量后,可以考虑把它转换成一个集合(hashes = set(hashes)
),这样查找的速度会比线性查找快。