我有一个非常奇怪的问题。我有三个文件,其中包含一列数字。我需要从第一个文件中获取唯一值,这些值在第二个和第三个文件中不存在。
我尝试过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
答案 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.csv
和third.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