给定n个词典,编写一个函数,返回一个包含重复键值列表的唯一字典。
示例:
d1 = {'a': 1, 'b': 2}
d2 = {'c': 3, 'b': 4}
d3 = {'a': 5, 'd': 6}
结果:
>>> newdict
{'c': 3, 'd': 6, 'a': [1, 5], 'b': [2, 4]}
到目前为止我的代码:
>>> def merge_dicts(*dicts):
... x = []
... for item in dicts:
... x.append(item)
... return x
...
>>> merge_dicts(d1, d2, d3)
[{'a': 1, 'b': 2}, {'c': 3, 'b': 4}, {'a': 5, 'd': 6}]
生成一个新词典的最佳方法是什么,该词典会产生这些重复键的值列表?
答案 0 :(得分:8)
Python为此提供了一个简单而快速的解决方案:collections
模块中的defaultdict
。从文档中的示例:
使用
list
作为default_factory
,可以很容易地对序列进行分组 键值对进入列表字典:>>> s = [('黄色',1),('蓝色',2),('黄色',3),('蓝色和#39; ;,4),(' red',1)]
>>> d = defaultdict(list)
>>>对于k,v在s中:
...... d [k] .append(v)
...
>>> d.items() [('蓝色',[2,4]),('红色',1),('黄色',[1,3] )]第一次遇到每个密钥时,它还没有进入 映射;所以使用。自动创建一个条目
default_factory
函数返回一个空列表。该 然后list.append()
操作将值附加到新列表。什么时候 再次遇到键,查找正常进行(返回 该键的列表)和list.append()
操作添加另一个 值列表。
在你的情况下,这大致是:
import collections
def merge_dicts(*dicts):
res = collections.defaultdict(list)
for d in dicts:
for k, v in d.iteritems():
res[k].append(v)
return res
>>> merge_dicts(d1, d2, d3)
defaultdict(<type 'list'>, {'a': [1, 5], 'c': [3], 'b': [2, 4], 'd': [6]})
答案 1 :(得分:3)
def merge_dicts(*dicts):
d = {}
for dict in dicts:
for key in dict:
try:
d[key].append(dict[key])
except KeyError:
d[key] = [dict[key]]
return d
这回归:
{'a': [1, 5], 'b': [2, 4], 'c': [3], 'd': [6]}
这个问题略有不同。这里所有字典值都是列表。如果长度为1的列表不需要,则添加:
for key in d:
if len(d[key]) == 1:
d[key] = d[key][0]
在return d
语句之前。但是,我无法想象你什么时候想要删除列表。 (考虑将列表作为值的情况;然后删除项目周围的列表会导致模糊的情况。)