【问题标题】:Merge dictionaries retaining values for duplicate keys合并字典,保留重复键的值
【发布时间】:2014-09-04 21:07:11
【问题描述】:

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

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

【问题讨论】:

  • d1= ['a':1, 'b':2] 字典的语法错误,应该是 d1= {'a':1, 'b':2}

标签: python merge duplicates


【解决方案1】:

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

使用list作为default_factory,很容易对一个序列进行分组 键值对到列表字典中:

>>> s = [('黄色', 1), ('蓝色', 2), ('黄色', 3), ('蓝色', 4), ('红色', 1)] >>> d = defaultdict(列表)
>>> for k, v in 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]})

【讨论】:

    【解决方案2】:
    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 语句之前。但是,我真的无法想象您何时想要删除该列表。 (考虑将列表作为值的情况;然后删除项目周围的列表会导致模棱两可的情况。)

    【讨论】:

      猜你喜欢
      • 2023-03-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-12-10
      • 2023-02-03
      • 1970-01-01
      相关资源
      最近更新 更多