列表转换为每个键具有多个值的字典转换?
问题描述:
我有持有对键/值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',)}
是否有完成这个任务,更优雅,Python的解决方案吗?
答
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使用列表作为值,这将在最后一行被转换为元组。这样你就可以追加到列表中而不会在主循环中重新创建元组。
+1
+1更好,这是一个新的工具。 – 2011-03-22 12:14:40
答
使用列表,而不是作为元组字典值:
l=[ [1, 'A'], [1, 'B'], [2, 'C'] ]
d={}
for key, val in l:
d.setdefault(key, []).append(val)
print d
答
的关键是已经排序在输入列表中?如果是这样的话,你有一个实用的解决方案:
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',)}
答
这种方法比较有效,相当紧凑:
reduce(lambda x, (k,v): x[k].append(v) or x, l, defaultdict(list))
+0
不错,但在python 3.5或更高版本中无效 – Davy 2017-05-15 19:42:35
S/multilpe /多 – vstrien 2011-03-21 13:36:24
'has_key'是的道路上的垃圾箱Python历史记录 - 如果您必须测试字典中是否存在密钥,请使用新的语法“if key in dict:'。但是对于你的问题的“答案”是@ eumiro的defaultdict方法。 – PaulMcG 2011-03-21 13:43:58
@vstrien谢谢。添加一个'/ g'会使它更通用:-) – 2011-03-21 13:51:57