2013-10-09 2 views
1

나는 목록 "GO_file"라고했다 :그룹화 항목

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

내가로 변환하려면 :

A : 12, 13, 14

B 1,

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  

5 그러나,이 코드에만 추가 키 하나만 값 :

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

제안 사항에 감사드립니다.

답변

2

코드는 몇 가지 문제

  1. 이 당신의 GO_ID의 중복, 그리고 당신 만의 고유 걱정하는 것이있다. 그래서 당신은 키를 생성하는 defaultdict(set) 대신
  2. defaultdict(list) 귀하의 분할 알고리즘을 필요로하고 값이
  3. GO_dict[gene_id] = GO_id 버그가, 간단하게 추가하는 대신 DICT 마지막 값을 할당합니다.

상기 코드의 가능한 보정 용액

>>> 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