преобразование списка в словарь с несколькими значениями на ключ? - PullRequest
51 голосов
/ 21 марта 2011

У меня есть список Python, который содержит пары ключ / значение:

l=[ [1, 'A'], [1, 'B'], [2, 'C'] ]

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

{ 1:('A', 'B'), 2:('C',) }

Итеративное решение тривиально:

l=[ [1, 'A'], [1, 'B'], [2, 'C'] ]
d={}
for pair in l:
    if d.has_key(pair[0]):
        d[pair[0]]=d[pair[0]]+tuple(pair[1])
    else:
        d[pair[0]]=tuple(pair[1])

print d

{1: ('A', 'B'), 2: ('C',)}

Есть ли более элегантное решение Pythonic для этой задачи?

Ответы [ 4 ]

49 голосов
/ 21 марта 2011
from collections import defaultdict

d1 = defaultdict(list)

for k, v in l:
    d1[k].append(v)

d = dict((k, tuple(v)) for k, v in d1.iteritems())

d содержит теперь {1: ('A', 'B'), 2: ('C',)}

d1 - временный defaultdict со списками в качестве значений, которые будут преобразованы в кортежи в последней строке. Таким образом, вы добавляете в списки, а не воссоздаете кортежи в основном цикле.

10 голосов
/ 19 февраля 2013

Этот метод относительно эффективен и довольно компактен:

reduce(lambda x, (k,v): x[k].append(v) or x, l, defaultdict(list))

В Python3 это становится (делает экспорт явным):

dict(functools.reduce(lambda x, d: x[d[0]].append(d[1]) or x, l, collections.defaultdict(list)))

Обратите внимание, что за редукцией перешли в functools и что лямбды больше не принимают кортежи. Эта версия все еще работает в 2.6 и 2.7.

9 голосов
/ 21 марта 2011

Использование списков вместо кортежей в качестве значений dict:

l=[ [1, 'A'], [1, 'B'], [2, 'C'] ]
d={}
for key, val in l:
    d.setdefault(key, []).append(val)

print d
3 голосов
/ 21 марта 2011

Клавиши уже отсортированы в списке ввода?Если это так, у вас есть функциональное решение:

import itertools

lst = [(1, 'A'), (1, 'B'), (2, 'C')]
dct = dict((key, tuple(v for (k, v) in pairs)) 
           for (key, pairs) in itertools.groupby(lst, lambda pair: pair[0]))
print dct
# {1: ('A', 'B'), 2: ('C',)}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...