比较 2 个输入文件的行,并输出差异的第三个文件



我有一个功能,允许我输入两个文件的文本文件,比较这些文本文件,最后创建第三个具有差异的文件。它适用于文件中的每一行,要使其正常工作,文件 1 和文件 2 中的整行文本必须相似才能注册。这是我的问题,我希望仅根据冒号后面的第一个单词将行与类似的行进行比较 - 冒号后面的文本不需要相同。

文件的结构是这样的;

文件 1 示例:

A:dog 
B:cat 
C:bird 
D:cow 
E:pig

文件 2 示例:

B:sheep
D:duck

我希望新创建的文件(文件 3)的输出具有以下内容:

A:dog
C:bird
E:pig

我希望该函数仅根据分号之前的第一个字符串(字母)输出文件 1 中不在文件 2 中的条目。目前,仅当文件 2 中的整行文本与文件 1 相同时,此操作才有效:

def comparison(F1,F2,F3):
   with open(F1, 'r') as f:
      d=set(f.readlines())
   with open(F2, 'r') as f:
      e=set(f.readlines())
   open(F3, 'a').close()
   with open(F3, 'a') as f:
      for line in list(d-e):
         f.write(line)
comparison('file1.txt','file2.txt','file3.txt')

我主要尝试使用line.split(':')[0]来抓取冒号之前的第一个字符串进行比较,但没有成功。

这是一个快速的解释器会话,用于显示使用 defaultdict 的过程。我会留给你填写文件 I/O。

>>> from collections import defaultdict
>>> list1 = ['a: xyz', 'b:123']
>>> list2 = ['a: dupe', 'c:456']
>>> d = defaultdict(list)
>>> for item in list1 + list2:
...     k,v = item.split(':')
...     d[k].append(v)
... 
>>> d
defaultdict(<type 'list'>, {'a': [' xyz', ' dupe'], 'c': ['456'], 'b': ['123']})
>>> ['{}:{}'.format(k,d[k][0]) for k in d if len(d[k]) == 1]
['c:456', 'b:123']

更新:根据请求提供文件 I/O 的示例。

from collection import defaultdict
list1 = open('file1.txt', 'r').readlines()
list2 = open('file2.txt', 'r').readlines()
d = defaultdict(list)
for item in list1 + list2:
    k,v = item.split(':')
    d[k].append(v)
with open('file3.txt', 'a') as output:
    output.writelines(['{}:{}n'.format(k,d[k][0]) for k in d if len(d[k]) == 1])

用英语解开最后一行,这意味着:

  • 逐步执行 d 中的键(我们的字典)
  • 忽略我们为该键添加了多个项目的项目(非唯一键)
  • 对于我们不会忽略的每个项目(是唯一的),格式化键和值返回"k:v"字符串并添加换行符
  • 对于重新组合的字符串集合(加上换行符),编写整个事情都归结为我们的文件。

嗯,有很多方法可以实现你的目标。实际上你们很接近。使用集合来处理值的想法是评估每个文件中两个列表之间的差异的好方法。但是,您需要将冒号之前的值与冒号之后的值分开,否则您将比较整行,这在您的情况下是错误的。获得差异后,您需要根据差异检索两个文件中的整行,以将它们写入新文件中。

因此,解决方案的一个想法是:当您读取一个文件时,您将每一行保存在字典中,以便将来可检索,并且还将冒号之前的值保存在一个集合中(每个文件一组)以评估值的差异(就像您已经做的那样)。

实际上,这意味着:

d = {}  # Our dictionary to store the lines
a = set()  # a set for the first file
b = set()  # a set for the second file
with open('file1') as fp:
    for line in fp:
        key, value = line.split(':')  # this separate the values in each line
        d[key] = value.strip()  # add one line to the dictionary
        a.add(key)  # save just the value from the colon left

然后,您需要与第二个文件相同。也许你会把它作为一个函数来让你的代码摇滚和更易于维护。

在此之后,您将拥有一本完整的词典。由于您不想写入重复值,因此我们的代码可以覆盖一些值。

现在,您需要评估差异。你这样做的方式很好。但是,如果您知道第一个文件比第二个文件具有更多的值,并且可能还有其他问题,它就会起作用。您需要查看设置方法才能正确实现此目的(提示:并集和交集),但让我们按照您的方式进行操作:

diff = a - b

最后,让我们根据我们的差异编写从字典中检索它们的结果:

with open('results', 'w') as fp:
    for key in diff:  # you can use sorted(diff) instead just diff here
        fp.write("{0}:{1}n".format(key, d[key]))

当然,这种方式不是更python的方式,但它是某种直截了当的。其他答案可能比这个更简单。

使用应将文件放入 CSV 格式。因此,只需将它们放在 excel 中并将其另存为 CSV。

这样做之后。

f = open('file1.csv')
csv_f = csv.reader(f)
animals1 = []
for row in csv_f:
    animals1.append(row[0])   #[] put number in there. 0 = first Column 
f.close()
f = open('file2.csv')
csv_f = csv.reader(f)
animals2 = []
for row in csv_f:
    animals2.append(row[0])      
f.close()

animals1 = set(animals1)
animals2 = set(animals2)
print animals1.difference(aniamls2)

所以这段代码基本上读取你的CSV文件,并打印出差异。您可以实现这一点并将其写入新文件。

编辑:警告,根据对这个答案的评论:这种方法不是解决这个问题的最佳方法。但它似乎确实回答了用户根据他的进一步评论提出的问题......

OP要求一种"更简单"的方法来做到这一点,而无需字典。 这可以通过读取每个文件的所有行,然后仅获取每行的第一个字母来完成。 然后根据 file2 中的字母数组过滤数据。 这将非常依赖于文本文件的特定格式,以及 file1 被 file2 过滤的事实,反之亦然。但是,也就是说,执行此操作的python应该看起来像这样(行号来自我的文本编辑器,而不是代码的一部分):

1 f=open("./file1.txt","r")
2 data1=f.readlines()
3 letter1=[]
4 f.close()
5 
6 g=open("./file2.txt","r")
7 data2=g.readlines()
8 letter2=[]
9 g.close()
10 
11 #just take the first character (the 'A', 'B', etc)
12 for dat in data1:
13     letter1.append(dat[0]) 
14 for dat in data2:
15     letter2.append(dat[0])
16 
17 h=open("output.txt","w")
18 for dat in data1:
19     if dat[0] not in letter2:
20         h.write(dat)
21 
22 h.close()

相关内容

  • 没有找到相关文章

最新更新