2013-01-02 24 views
1

所以我有一個看起來像一些文件刪除重複項:追加多個文件,並使用字典

snpID Gene 
rs1 ABC1 
rs2 ABC1 
rs3 ABC25 
rs4 PT4 
rs5 MTND24 

在不同的文件中會有其他snpIDs和基因對,但有可能是一個給定的snpID但重複的相應的「基因」關聯可能不同。對於如:

snpID Gene 
rs100 URX1 
rs95 KL4 
rs1 ABC1 
rs2 ABC1-MHT5 
rs3 ABC25 
rs4 PT4-FIL42 

我想要做的就是在文件中附加的所有內容,並刪除重複的,如果他們有相同的snpID和基因配對。而如果一個snpID相應的基因不同,它必須進入同一行 對於上面的例子應該是這樣的:

snpID Gene 
rs1 ABC1 
rs2 ABC1, ABC1-MHT5 
rs3 ABC25 
rs4 PT4, PT4-FIL42 
rs5 MTND2 
rs100 URX1 
rs95 KL4 

我想我可以通過創建字典實現這一目標。

import glob 
file_list = glob.glob('annotations.*') 
dict_snps_genes = {} 
for filename in file_list: 
    with open(filename) as fileA: 
     for line in fileA: 
      col0 = line.split()[0] 
      col1 = line.split()[1] 
      dict_snps_genes[col0] = col1 

unique_dict_snps = {} 
for key,value in dict_snps_genes: 
    if key not in unique_dict_snps.keys(): 
     unique_dict_snps_genes[key] = value 

我進一步移動之前測試這一點,這給了我這樣的錯誤:

ValueError: too many values to unpack 

PS:每個文件都有8000左右snpId基因對,有超過5個文件

想法如何通過這個!

+0

代替'COL0 = line.split()[0]'和'COL1 = line.split()[1]',可以使用只有一個函數調用:'COL0,COL1 = line.split()' – 2013-01-02 15:09:33

回答

5

您遍歷鍵,但嘗試指派那些既鍵和值的變量:

for key,value in dict_snps_genes: 

變化,要遍歷.items()

for key,value in dict_snps_genes.items(): 

或者更好的是,如果在Python 2.x,使用`.iteritems():

for key,value in dict_snps_genes.iteritems(): 

請注意,您讀取文件的方式,你o永遠不會爲任何給定的snpID存儲最後讀取的基因;如果您找到該ID的另一個條目,則覆蓋前一個條目。

就個人而言,我會使用collections.defaultdict()set默認:

import glob 
import collections 

file_list = glob.glob('annotations.*') 
snps_genes = collections.defaultdict(set) 
for filename in file_list: 
    with open(filename) as fileA: 
     for line in fileA: 
      snpid, gene = line.strip().split(None, 1) 
      snps_genes[snpid].add(gene) 

現在snps_genes值是一組基因,每一個獨特的。請注意,我拆你的行成2塊上的空白(.split(None, 1)),所以,如果有在基因值的任何空白,它會被存儲爲這樣的:

>>> 'id gene with whitespace'.split(None, 1) 
['id', 'gene with whitespace'] 

通過使用`snpid,基因」左手工賦值表達式Python將分割的結果分配給一個單獨的變量;一個方便的技巧來保存一行代碼。

要將其輸出到新文件,只需循環所產生的snps_genes結構即可。這裏有一個排序的一切:

for id in sorted(snps_genes): 
    print id, ', '.join(sorted(snps_genes[id])) 
+0

正如所寫的,我不認爲第二個循環做了什麼,但。 'unique_dict_snps'不會成爲'dict_snps_genes'的副本嗎? – DSM

+0

@DSM:我添加了一段關於如何讀取文件的部分。文件被閱讀的方式,永遠不會有*任何愚蠢無論如何。 –

+0

嗯...基本上相同的答案,除了我喜歡使用'inputfile'這樣的案例 –

1

你可以col1 = line.split()[1]後更換行:

if col0 in dict_snps_genes: 
    dict_snps_genes[col0].add(col1) 
else: 
    dict_snps_genes[col0] = set([col1]) 

你可以閱讀更多關於套here

2

我將它寫成如下:

from glob import glob 
import fileinput 

infiles = glob('annotations.*') 
lines = fileinput.input(infiles) 
rows = (line.split() for line in lines) 

from collections import defaultdict 
dd = defaultdict(list) 
for row in rows: 
    dd[row[0]].append(row[1]) 

如果值是唯一的,則:

dd = defaultdict(set) 
for row in rows: 
    dd[row[0]].add(row[1]) 

然後從那裏....

+0

在導入「inputfile」函數時給我一個錯誤 – jules

+0

@jules我打錯了 - 應該是'import fileinput' - 編輯(這就是你直接輸入到SO中得到的結果!) –

1

爲什麼不只是做:

import glob 
files = glob.glob('annotations.*') 
d = {} 
for f in files: 
    with open(f) as f: 
     for line in f: 
      col0, col1 = line.split() 
      if col0 not in d: 
       d[col0] = [col1] 
      elif col1 not in d[col0]: 
       d[col0].append(col1) 

將導致成:

d = { 
    "rs95": ['KL4'], 
    "snpID": ['Gene'], 
    "rs1": ['ABC1'], 
    "rs2": ['ABC1', 'ABC1-MHT5'], 
    "rs3": ['ABC25'], 
    "rs4": ['PT4', 'PT4-FIL42'], 
    "rs5": ['MTND24'], 
    "rs100": ['URX1'] 
} 
+0

這可以完美地去除重複的內容,但是我怎樣才能統一字典中每個鍵的值呢?我不想讓相同的基因名稱重新出現。 – jules

+0

同上,你可以使用集合。用你手中的列表,用'set(listname)'創建一個集合。 – whatyouhide

+0

Ups,沒有注意到,修復。對我來說似乎是最好的解決方案,不需要'set'或'defaultdict'。 – 2013-01-03 14:02:42