关于python:列表转换为每个键有多个值的字典转换?

list to dictionary conversion with multiple values per key?

我有一个python列表,其中包含成对的键/值:

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

我要将列表转换为字典,其中每个键的多个值将聚合为一个元组:

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

迭代解很简单:

1
2
3
4
5
6
7
8
9
10
11
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',)}

对于这项任务,是否有一个更优雅的、Python式的解决方案?


1
2
3
4
5
6
7
8
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())

现在的容器

这是一个临时性的缺陷,列表作为价值,将在最后一条线上转换为图普。这条路附着列表,而不是主要环路的娱乐管。


This method is relatively efficient and quite compact:

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

In Python3 this becomes(making exports explicit):

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

注:减少了对函子的移动,而Lambdas不接受长管。This version still works in 2.6 and 2.7.


Using lists instead of tuples as dict values:

ZZU1


输入列表中的钥匙总会出来吗?如果是这样,你有一个功能性的解决办法:

1
2
3
4
5
6
7
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',)}