合并字典保留重复键的值

时间:2014-07-14 20:17:23

标签: python merge duplicates

给定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}]

生成一个新词典的最佳方法是什么,该词典会产生这些重复键的值列表?

2 个答案:

答案 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语句之前。但是,我无法想象你什么时候想要删除列表。 (考虑将列表作为值的情况;然后删除项目周围的列表会导致模糊的情况。)