两个文件比较

时间:2016-06-23 23:35:52

标签: python list shell comparison

我有一个非常奇怪的问题。我有三个文件,其中包含一列数字。我需要从第一个文件中获取唯一值,这些值在第二个和第三个文件中不存在。

我尝试过Python:

for e in firstfile:
    if e not in secondfile:
        resultfile.append(e)
return resultfile

第三档同样如此。

我尝试了uniq,sort,diff,一些awk脚本和linux shell中的comm,如下所示:boundingRectWithSize(_:options:attributes:context:)

但是我每次得到的唯一结果就是它的第一个文件中的相同数量。我根本得不到它!

也许,我错过了什么?也许它是格式化的东西?但是,我经常检查过很多次。以下是文件:Fast way of finding lines in one file that are not in another?

P.S。后来我觉得根本没有独特的线条,但是我手动检查了它,第一个文件中的一些数字是唯一的。

P.P.S。文件格式如下:

380500100000 
380500100001 
380500100002 
380500100003 
380500100004    
380500100005 
380500100008 
380500100020 
380500100022 
380500100050    
380500100070 
380500100080

3 个答案:

答案 0 :(得分:2)

出了什么问题

  

和第三个文件相同

如果你真的对第三个文件做同样的事情,即比较第一个文件和第三个文件的原始内容,你可以引入不在第二个文件但在第三个文件中的项目的重复项。例如:

file 1:
1
2
3

file 2:
1

file 3:
2

处理文件2后,resultfile将包含2和3.然后在处理文件3后,resultfile将包含2和3(从第一次运行)加上 1和3,即2,3,1,3。然而,结果应该是3。

您的代码中不清楚您是否实际将每次运行的输出写入文件 resultfile。如果您是,那么您应该将其用作第二次和后续运行的输入,不要再次处理第一个文件。

更好的解决方法

如果您不需要保留第一个文件中的行顺序,可以使用set.difference(),如下所示:

with open('file1') as f1, open('file2') as f2, open('file3') as f3:
    unique_f1 = set(f1).difference(f2, f3)

请注意,这将包含文件中存在的任何空格(包括换行符)。如果你想忽略每行的前导和尾随空格:

from itertools import chain

with open('file1') as f1, open('file2') as f2, open('file3') as f3:
    unique_f1 = set(map(str.strip, f1)).difference(map(str.strip, chain(f2, f3)))

以上假设使用Python 3.如果您正在使用Python 2,那么可选择提高效率,导入itertools.imap并使用它代替map()

或者您可能希望将数据视为数字(我在这里假设float,但您可以使用int代替):

from itertools import chain

with open('file1') as f1, open('file2') as f2, open('file3') as f3:
    unique_f1 = set(map(float, f1)).difference(map(float, chain(f2, f3)))

答案 1 :(得分:0)

最简单的方法是将每个文件读入set,然后使用Python(非常有效的)设置操作进行比较。

file1 = set()
file2 = set()

for element in firstfile:
    file1.add(element)

for element in secondfile:
    file2.add(element)

unique = file1 - file2

答案 2 :(得分:0)

问题可能是first.csv严格是ASCII文本,而second.csvthird.csv是ASCII文本,CRLF行终止符。我建议你把它们改成相同的格式(ASCII文本可能效果最好)。

$ file first.csv
first.csv: ASCII text 

$ file second.csv
second.csv: ASCII text, with CRLF line terminators

$ file third.csv
third.csv: ASCII text, with CRLF line terminators