当我尝试比较两个大文件时遇到问题。我要做的是从一个文件中取一行,搜索另一个文件的所有行以进行匹配,如果没有,则将该行写入另一个文件。我能够通过下面的简单示例重新创建问题:
file1.txt(内容)
apple
banana
pear
peach
lime
file_old.txt(内容)
lime
apple
pear
peach
由于我在file1中寻找不在file_old中的行,我希望'banana'是输出文件中唯一显示的值。但是在输出文件“* fill_diff *”中,我显示:
apple
banana
banana
我的代码试图在文件中产生差异有什么问题?
def main():
file_old = open(r'C:\Users\test\Desktop\file_old.txt', 'r+')
file_new = open(r'C:\Users\test\Desktop\file1.txt', 'r+')
file_diff = open(r'C:\Users\test\Desktop\file_diff.txt', 'w')
for each_line in file_new:
for every_line in file_old:
if each_line == every_line:
break
file_diff.write(each_line)
file_old.close()
file_new.close()
file_diff.close()
main()
谢谢!
答案 0 :(得分:4)
srgerg的回答将起作用。
但是,多次读取文件将具有非常大的运行时复杂性。因此,如果文件(虽然很大)足够小以适应内存,那么您可以考虑将file_old
中的所有行放入数据结构中进行比较:
old_lines = set((line.strip() for line in open(r'C:\Users\test\Desktop\file_old.txt', 'r+')))
file_new = open(r'C:\Users\test\Desktop\file1.txt', 'r+')
file_diff = open(r'C:\Users\test\Desktop\file_diff.txt', 'w')
for line in file_new:
if line.strip() not in old_lines:
file_diff.write(line)
file_new.close()
file_diff.close()
希望这有帮助
答案 1 :(得分:2)
你可以先在O(n + n * log(n))中对两个文件进行排序,然后同时迭代这两个文件。
# sort file1 and file2 on disk or in memory
while len(file1) > 0 and len(file2) > 0:
while file1[0] < file2[0]:
diff.append(file1[0])
file1 = file1[1:]
while file1[0] > file2[0]:
diff.append(file2[0])
file2 = file2[1:]
while file1[0] == file2[0]:
file1 = file1[1:]
file2 = file2[1:]
diff = diff + file1 + file2 # add the rest to the diff
答案 2 :(得分:1)
您需要在循环的每次迭代开始时返回file_old
的开头。像这样:
for each_line in file_new:
file_old.seek(0)
for every_line in file_old:
...
此外,你最内层循环的逻辑似乎是错误的。我想你想要像
这样的东西for each_line in file_new:
file_old.seek(0)
found = False
for every_line in file_old:
if each_line == every_line:
found = True
break
if not found:
file_diff.write(each_line)
答案 3 :(得分:1)
FWIW,difflib module是为这种用例而设计的。
如果您需要手动执行,Python的集合可以使其更容易:
file_diff = open(r'C:\Users\test\Desktop\file_diff.txt', 'w')
oldlines = set(open(r'C:\Users\test\Desktop\file_old.txt', 'r'))
for line in open(r'C:\Users\test\Desktop\file1.txt', 'r'):
if line not in oldlines:
file_diff.write(line)
答案 4 :(得分:1)
我怀疑你想要以任何顺序错过行 ?
这是一个基于set()
的快速而肮脏的实现:
def readfile(name):
afile = open(name, 'r+')
lines = set([l.strip() for l in afile])
afile.close()
return lines
def main():
oldset = readfile(r'file_old.txt')
newset = readfile(r'file1.txt')
file_diff = open(r'file_diff.txt', 'w')
for diff in (newset - oldset):
file_diff.write(diff)
file_diff.close()
main()
对于非常大的输入文件,这可能无法很好地扩展。
答案 5 :(得分:0)
如果您不能假设文件已排序,那么我会做这样的事情
def diffUnsorted(fn1, fn2) :
return set([l.strip() for l in open(fn1) if l.strip() != ""]) - \
set([l.strip() for l in open(fn2) if l.strip() != ""])
如果您要处理大文件,我会选择一个先对文件进行排序的解决方案,这样可以获得O(n)时间和O(1)空间(不包括排序......) )。