列表转换为每个键有多个值的字典转换?

Ada*_*tan 52 python dictionary list type-conversion

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

l=[ [1, 'A'], [1, 'B'], [2, 'C'] ]
Run Code Online (Sandbox Code Playgroud)

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

{ 1:('A', 'B'), 2:('C',) }
Run Code Online (Sandbox Code Playgroud)

迭代解决方案是微不足道的:

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',)}
Run Code Online (Sandbox Code Playgroud)

是否有更优雅的Pythonic解决方案来完成这项任务?

eum*_*iro 52

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())
Run Code Online (Sandbox Code Playgroud)

d 现在包含 {1: ('A', 'B'), 2: ('C',)}

d1是一个临时的defaultdict,列表为值,将在最后一行转换为元组.这样,您将附加到列表,而不是在主循环中重新创建元组.

  • 从python3.x开始,你不能再使用`d1.iteritems()`了.如果你像我一样,把它改成`d1.items()` (3认同)

小智 10

这种方法相对有效且非常紧凑:

reduce(lambda x, (k,v): x[k].append(v) or x, l, defaultdict(list))
Run Code Online (Sandbox Code Playgroud)

在Python3中,这变为(使导出显式):

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

请注意,reduce已移至functools并且lambda不再接受元组.此版本仍适用于2.6和2.7.


Sve*_*ach 9

使用列表而不是元组作为dict值:

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

print d
Run Code Online (Sandbox Code Playgroud)