合并字典保留重复键的值

lag*_*zul 4 python merge duplicates

给定n个字典,编写一个函数,该函数将返回一个唯一字典,其中包含重复键的值列表.

例:

d1 = {'a': 1, 'b': 2}
d2 = {'c': 3, 'b': 4}
d3 = {'a': 5, 'd': 6}
Run Code Online (Sandbox Code Playgroud)

结果:

>>> newdict
{'c': 3, 'd': 6, 'a': [1, 5], 'b': [2, 4]}
Run Code Online (Sandbox Code Playgroud)

我的代码到目前为止:

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

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

imp*_*his 8

Python为此提供了一个简单而快速的解决方案:defaultdictcollections模块中.从文档中的示例:

使用listas default_factory,很容易将一系列键值对分组到列表字典中:

>>> s = [('yellow',1),('blue',2),('yellow',3),('blue',4),('red',1)]
>>> d = defaultdict(list)
>>> for k,v in s:
... d [k] .append(v)
...
>>> d.items()[('blue',[2,4]) ,('red',1),('yellow',[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]})
Run Code Online (Sandbox Code Playgroud)


DrV*_*DrV 4

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

这重新调整:

{'a': [1, 5], 'b': [2, 4], 'c': [3], 'd': [6]}
Run Code Online (Sandbox Code Playgroud)

这个问题略有不同。这里所有字典值都是列表。如果长度为 1 的列表不需要这样,则添加:

    for key in d:
        if len(d[key]) == 1:
            d[key] = d[key][0]
Run Code Online (Sandbox Code Playgroud)

在声明之前return d。然而,我真的无法想象你什么时候想要删除该列表。(考虑将列表作为值的情况;然后删除项目周围的列表会导致不明确的情况。)