2014-09-04 63 views
2
不同列表比較元件

我已經產生的兩個多組分列出與下面的腳本:從使用python

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])) 
+0

如果list2中有多個匹配項,會發生什麼? – 2014-09-04 15:50:31

+0

我假設如果有多個匹配他們應該*所有*被追加。 – 2014-09-04 15:54:11

回答

4

從表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的評論中學習,但我仍然留下它。

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')] 
+3

這樣做**的方式太多工作**。這需要M * N個循環(其中M和N是兩個列表的大小)。使用字典爲您提供M + N解決方案;例如每個列表循環*一次*。 – 2014-09-04 16:00:57

+0

如果list1的長度爲10,000個元素,而列表2的元素爲5,000個,那麼您的版本需要5000萬次迭代。我的只有15,000。 – 2014-09-04 16:02:04

+0

感謝您的闡述。我有一些舊的代碼去更新! – chishaku 2014-09-04 16:07:36