【问题标题】:Comparing elements from different lists using python使用python比较来自不同列表的元素
【发布时间】:2014-09-04 15:48:42
【问题描述】:

我使用以下脚本生成了两个多组件列表:

list1 = list()
for line in infile1.readlines():
    list1.append(line.split('\t'))

list2 = list()
for line in infile2.readlines():
    list2.append(line.split(‘\t’))

列表如下所示:

list1 = ('1960', 'chr17', '+', 'RNF213'), ('1963', 'chr16', '+', 'SF3B3'), ('1964', 'chr4', '-', 'GPRIN3')...

list2 = ('1482', 'miR-K12-1'), ('1018', 'miR-K12-4-5p'), ('1960', 'miR-K12-12')...

list1 中第一个条目的第一个元素(在本例中为“1960”)将匹配 list2 中一个或多个条目的第一个元素。我想做的是找到每个匹配项,然后将 list2 条目的最后一个元素添加到 list1 条目。所需输出的一个示例是:

('1960', 'chr17', '+', 'RNF213', 'miR-K12-12')

我试过了,但它什么也没返回:

result = []
for list1[0] in list1:
    if list1[0] == list2[0]:
        result.append((list1[0:], list2[1]))

【问题讨论】:

  • 如果list2中有多个匹配项会怎样?
  • 我假设如果有多个匹配项,它们应该 all 被追加。

标签: python list compare


【解决方案1】:

将列表 2 中的值放入字典中;第一列中的每个唯一值都指向第二列中的值列表。因为你有制表符分隔的值,所以你真的应该在这里使用csv module

import csv

lines2 = {}

with open(filename2, 'rb') as infile2:
    reader = csv.reader(infile2, delimiter='\t')
    for row in reader:
        lines2.setdefault(row[0], []).append(row[1])

dict.setdefault() 设置一个默认值(这里是一个列表对象),如果该键还没有出现在字典中。这允许我们将第一个值附加到一个空列表中,然后将其余值附加到已经存在的列表中。

现在您可以在处理其他文件时轻松查找匹配行:

with open(filename1, 'rb') as infile1:
    reader = csv.reader(infile1, delimiter='\t')
    for row in reader:
        row += lines2.get(row[0], [])
        print row

演示:

>>> import csv
>>> list1 = ['\t'.join(r) for r in [('1960', 'chr17', '+', 'RNF213'), ('1963', 'chr16', '+', 'SF3B3'), ('1964', 'chr4', '-', 'GPRIN3')]]
>>> list2 = ['\t'.join(r) for r in [('1482', 'miR-K12-1'), ('1018', 'miR-K12-4-5p'), ('1960', 'miR-K12-12')]]
>>> lines2 = {}
>>> reader = csv.reader(list2, delimiter='\t')
>>> for row in reader:
...     lines2.setdefault(row[0], []).append(row[1])
... 
>>> lines2
{'1482': ['miR-K12-1'], '1960': ['miR-K12-12'], '1018': ['miR-K12-4-5p']}
>>> reader = csv.reader(list1, delimiter='\t')
>>> for row in reader:
...     row += lines2.get(row[0], [])
...     print row
... 
['1960', 'chr17', '+', 'RNF213', 'miR-K12-12']
['1963', 'chr16', '+', 'SF3B3']
['1964', 'chr4', '-', 'GPRIN3']

【讨论】:

    【解决方案2】:

    编辑:不要使用这种方法。我将其保留,因为其他人可能能够从 @Martijn 的 cmets 中学习。

    list1 = [('1960', 'chr17', '+', 'RNF213'), ('1963', 'chr16', '+', 'SF3B3'), ('1964', 'chr4', '-', 'GPRIN3')]
    list2 = [('1482', 'miR-K12-1'), ('1018', 'miR-K12-4-5p'), ('1960', 'miR-K12-12')]
    
    results = []
    for x in list1:
        for y in list2:
            if x[0] == y[0]:
                results.append( x + (y[-1], ))
    print results
    >>>
    [('1960', 'chr17', '+', 'RNF213', 'miR-K12-12')]
    

    【讨论】:

    • 工作量太大。这需要 M * N 循环(其中 M 和 N 是两个列表的大小)。使用字典可以为您提供 M + N 解决方案;例如在每个列表上按顺序循环一次
    • 如果 list1 的长度为 10,000 个元素,而列表 2 包含 5,000 个元素,则您的版本需要 5000 万次迭代。我的只有 15,000 个。
    • 感谢您的说明。我有一些旧代码要更新!
    • 嗯想给“不要使用这种方法”+1
    • 谢谢!我试过你的方法,效果很好。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-08-01
    • 1970-01-01
    • 1970-01-01
    • 2020-09-20
    • 1970-01-01
    相关资源
    最近更新 更多