2013-10-09 21 views
1

我已經叫列表 「GO_file」:分組項目使用python defaultdic

GO_file = ["A_1 12", "A_2 13", "A_3 14", "A_4 12", "B_1 1", "B_2 1", "B_3 5"] 

我想將其轉換爲:

答:12,13,14

乙:1,5

from collections import defaultdict 
GO_file = ["A_1 12", "A_2 13", "A_3 14", "A_4 12", "B_1 1", "B_2 1" "B_3 5"] 

GO_dict = defaultdict(list) 
for GO_names in GO_file: 
    gene_id = GO_names.split("_")[0] 
    GO_id = GO_names.split(" ")[1:] 
    GO_dict[gene_id] = GO_id 
print GO_dict  

然而,這種代碼只追加密鑰和只有一個值:

defaultdict(<type 'list'>, {'A': ['12'], 'B': ['5']}) 

我很欣賞任何建議。

回答

2

你的代碼中有幾個問題

  1. ,我們在您GO_ID重複,你似乎只關心獨特。所以,你需要的不是defaultdict(set)defaultdict(list)
  2. 將拆分算法生成密鑰和值是越野車
  3. GO_dict[gene_id] = GO_id,簡單地分配其追加的最後一個值的字典來代替。

一種可能的校正溶液

>>> GO_dict = defaultdict(set) 
>>> for GO_names in GO_file: 
    gene_id,_,GO_id = GO_names.partition(" ") 
    gene_id = gene_id.split("_")[0] 
    GO_dict[gene_id].add(GO_id) 


>>> print GO_dict 
defaultdict(<type 'set'>, {'A': set(['13', '12', '14']), 'B': set(['1', '5'])}) 

一個可能的問題與上面的代碼,則元素的順序是不能保證。不幸的是,默認的庫不提供OrderedSet,但我們可以輕鬆地定製OrderedDict到服務器我們的目的

>>> GO_dict = defaultdict(OrderedDict) 
>>> for GO_names in GO_file: 
    gene_id,_,GO_id = GO_names.partition(" ") 
    gene_id = gene_id.split("_")[0] 
    GO_dict[gene_id][GO_id] = None 


>>> OrderedDict([('A', ['12', '13', '14']), ('B', ['1', '5'])]) 
OrderedDict([('A', ['12', '13', '14']), ('B', ['1', '5'])]) 

存在這樣的情況,因爲這一個,我相信,在itertools解決方案更優雅比使用defaultdict

>>> from itertools import groupby 
>>> from operator import itemgetter 
>>> GO_file_kv = [(key.split("_")[0], value) 
        for key, value in (elem.split(" ") for elem in GO_file)] 
>>> {key: OrderedDict.fromkeys([e for _, e in value]).keys() 
    for key, value in groupby(sorted(GO_file_kv, key=itemgetter(0)), 
         key=itemgetter(0)) 
} 
{'A': ['12', '13', '14'], 'B': ['1', '5']} 
+0

謝謝Abhijit的綜合答案! – user690462