【问题标题】:compare file line by line python逐行比较文件python
【发布时间】:2013-05-14 10:25:48
【问题描述】:

按第一个索引遍历排序列表的最优雅的方法是什么?输入:

Meni22   xxxx xxxx
Meni32_2 xxxx xxxx
Meni32_2 xxxx xxxx
Meni45_1 xxxx xxxx
Meni45_1 xxxx xxxx
Meni45   xxxx xxxx

是不是一行一行地走下去:

list1 = []
list2 = []
for line in input:
    if line[0] not in list1:
    list.append(line)
else:
    list2.append(line)

示例显然行不通。它添加 line[0] 的第一个匹配项并继续。我宁愿让它遍历列表,将它只找到一次的行添加到 list1 中,然后再添加到 list2 中。

脚本之后:

List1:

Meni22   xxxx xxxx
Meni45   xxxx xxxx

List2: 

Meni45_1 xxxx xxxx
Meni45_1 xxxx xxxx
Meni32_2 xxxx xxxx
Meni32_2 xxxx xxxx

【问题讨论】:

  • 每一行开头的xxxx xxxx 是否相同?
  • 您的输入有多少列?两个还是三个?
  • 目前尚不清楚您要在这里实现什么。基于“脚本之后”部分,您是否只想根据第一个标记是否包含下划线将输入分成两个列表?
  • @Wooble 不,它们在每种情况下都不同。
  • @Aya 不,我不想拆分 bt 下划线。他们现在被这样排序只是偶然。

标签: python list compare


【解决方案1】:

由于文件已排序,可以使用groupby

from itertools import groupby
list1, list2 = res = [], []
with open('file1.txt', 'rb') as fin:
    for k,g in groupby(fin, key=lambda x:x.partition(' ')[0]):
        g = list(g)
        res[len(g) > 1] += g

或者如果你更喜欢这个更长的版本

from itertools import groupby
list1, list2 = [], []
with open('file1.txt', 'rb') as fin:
    for k,g in groupby(fin, key=lambda x:x.partition(' ')[0]):
        g = list(g)
        if len(g) > 1:
            list2 += g
        else:
            list1 += g

【讨论】:

    【解决方案2】:

    你可以使用collections.Counter:

    from collections import Counter
    lis1 = []
    lis2 = []
    with open("abc") as f:
        c = Counter(line.split()[0] for line in f)
    
    for key,val in c.items():
        if val == 1:
            lis1.append(key)
        else:
            lis2.extend([key]*val)
    print lis1
    print lis2
    

    输出:

    ['Meni45', 'Meni22']
    ['Meni32_2', 'Meni32_2', 'Meni45_1', 'Meni45_1']
    

    编辑:

    from collections import defaultdict
    lis1 = []
    lis2 = []
    
    with open("abc") as f:
        dic = defaultdict(list)
        for line in f:
            spl =line.split()
            dic[spl[0]].append(spl[1:])
    
    for key,val in dic.items():
        if len(val) == 1:
            lis1.append(key)
        else:
            lis2.append(key)
    print lis1
    print lis2
    
    print dic["Meni32_2"]  #access columns related to any key from the the dict
    

    输出:

    ['Meni45', 'Meni22']
    ['Meni32_2', 'Meni45_1']
    [['xxxx', 'xxxx'], ['xxxx', 'xxxx']]
    

    【讨论】:

    • 工作得很好,但由于我们在这里用 [0] 分割,它会从列表中删除其他列。那不是故意的。有什么办法解决这个问题?
    • @jester112358 是的,在这种情况下您可以使用collections.defaultdict,请参阅我更新的解决方案。
    • @AshwiniChaudhary 非常感谢。对我帮助很大!
    • @AshwiniChaudhary 您已经提供了很多帮助,但是如果您有时间并且这很容易:如果我想编辑列表,最简单的方法是什么?在这种情况下: Fam_c355_1 ['7322', '3'] ['7344', '4'] 如果键的第二个值低于 x,我想打印一些东西。另外:如果我把它放到excel中,列表真的很乱,因为我不能像普通列表那样使用“\n,\t”等。这里最简单的方法是什么?
    • @jester112358 你可以比较一下值:if int(dic['Fam_355_1'][0][1])<some_value: print something
    【解决方案3】:

    考虑使用difflib

    import difflib
    
    d = difflib.Differ()
    fa = open('a.txt'); fb = open('b.txt')
    
    diff = d.compare("".join(fa.readlines()), "".join(fb.readlines()))
    print ''.join(list(diff))
    
    fa.close(); fb.close()
    

    【讨论】:

      猜你喜欢
      • 2014-08-24
      • 1970-01-01
      • 2013-03-14
      • 1970-01-01
      • 1970-01-01
      • 2015-12-02
      • 2013-10-01
      • 2022-01-08
      相关资源
      最近更新 更多