2015-03-02 2 views
2

У меня есть коллекция, которая выглядит следующим образом:Какой самый чистый (самый Pythonic) способ создания словаря со значениями списка из последовательности?

stuff = [('key1', 1), ('key2', 2), ('key3', 3), 
     ('key1', 11), ('key2', 22), ('key3', 33), 
     ('key1', 111), ('key2', 222), ('key3', 333), 
     ] 
# Note: values aren't actually that nice. That would make this easy. 

Я хочу, чтобы превратить его в словарь, который выглядит следующим образом:

dict_stuff = {'key1': [1, 11, 111], 
       'key2': [2, 22, 222], 
       'key3': [3, 33, 333], 
       } 

Что самый хороший способ преобразовать эти данные? Первый метод, который приходит на ум, заключается в следующем:

dict_stuff = {} 
for k,v in stuff: 
    dict[k] = dict.get(k, []) 
    dict[k].append(v) 

Это самый чистый способ сделать это?

+0

если 'stuff' гарантировалась быть отсортированы по "ключ", я хотел бы использовать' itertools.groupby'. Поскольку кажется, что это не так, 'collections.defaultdict', вероятно, будет вашим лучшим лучшим выбором (как показано в ответах) – mgilson

ответ

2

Вы можете использовать dict.setdefault, как этот

dict_stuff = {} 
for key, value in stuff: 
    dict_stuff.setdefault(key, []).append(value) 

Он говорит, что, если key не существует в словаре, а затем использовать второй параметр в качестве значения по умолчанию для него, в противном случае вернуть фактическое значение, соответствующее key.

У нас также есть встроенный класс dict, который поможет вам справиться с такими случаями, как collections.defaultdict.

from collections import defaultdict 
dict_stuff = defaultdict(list) 
for key, value in stuff: 
    dict_stuff[key].append(value) 

Здесь, если key не существует в defaultdict объекта, функция завод передается в defaultdict конструктор будет вызываться для создания объекта значения.

1

В collections находится defaultdict.

>>> from collections import defaultdict 
>>> dict_stuff = defaultdict(list) # this will make the value for new keys become default to an empty list 
>>> stuff = [('key1', 1), ('key2', 2), ('key3', 3), 
...   ('key1', 11), ('key2', 22), ('key3', 33), 
...   ('key1', 111), ('key2', 222), ('key3', 333), 
...   ] 
>>> 
>>> for k, v in stuff: 
...  dict_stuff[k].append(v) 
... 
>>> dict_stuff 
defaultdict(<type 'list'>, {'key3': [3, 33, 333], 'key2': [2, 22, 222], 'key1': [1, 11, 111]}) 
+2

Обратите внимание, что если в какой-то более поздний момент вы хотите отключить поведение по умолчанию по умолчанию dict , вы просто установите для атрибута 'default_factory' значение' None'. например 'dict_stuff.default_factory = None' – mgilson

0
stuff_dict = {} 
for k, v in stuff: 
    if stuff_dict.has_key(k): 
     stuff_dict[k].append(v) 
    else: 
     stuff_dict[k] = [v] 


print stuff_dict 
{'key3': [3, 33, 333], 'key2': [2, 22, 222], 'key1': [1, 11, 111]} 
+0

' has_key' устарел, вы можете просто сделать 'if k in stuff_dict:' – thefourtheye

Смежные вопросы