Ваш код имеет несколько проблем
- Есть дубликаты в вашем GO_ID, и вы, кажется, только заботиться о уникальной. Так что вам нужна
defaultdict(set)
вместо defaultdict(list)
- Вашего раздвоения алгоритм для генерации ключа и значение глючит
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']}
Спасибо Абхиджит за комплексный ответ! – user690462