【问题标题】:How to merge two dicts and combine common keys?如何合并两个字典并组合公共键?
【发布时间】:2019-11-11 16:43:50
【问题描述】:

我想知道是否存在任何 python 函数来合并两个字典并组合具有公共键的所有值。

我找到了追加两个字典、合并两个字典但不合并其值的函数。

例子:

D1 = [{k1: v01},            {k3: v03}, {k4: v04},}],
D2 = [{k1: v11}, {k2: v12},            {k4: v14},}],

这应该是预期的结果:

D3 = [
   {k1: [v01, v11]},
   {k2: [     v12]},
   {K3: [v03     ]},
   {k4: [v04, v14]},
 ]

【问题讨论】:

  • D3 不只是一个字典而不是单键字典列表有什么原因吗?这是一种非常笨拙的格式。
  • 标题、正文和发布的代码/数据不匹配 - 您正在询问如何合并两个字典和组合键,但您的数据显示了几个字典的两个列表;您的输出显示了几个字典的列表。
  • 重复值怎么办?是否应该添加两次?
  • 我对 python 很陌生,对于我命名列表、字典等的错误,我很抱歉。所有信息都在我必须转换的 JSON 文件中。

标签: python python-3.x dictionary merge


【解决方案1】:

这里没有内置函数,但您可以为此使用 defaultdict:

from collections import defaultdict
d = defaultdict(list)
for other in [d1, d1]:
    for k, v in other.items():
        d[k].append(v)

【讨论】:

  • OP 的最终期望输出是一个列表。
  • 我认为这是格式错误,对我来说没有任何意义
  • 我也不推荐使用列表,但应该很容易从 dict 转换为记录列表。
【解决方案2】:

解决方案,无需导入任何内容:

# First initialize data, done correctly here.
D1 = [{'k1': 'v01'},            {'k3': 'v03'}, {'k4': 'v04'}]
D2 = [{'k1': 'v11'}, {'k2': 'v12'},            {'k4': 'v14'}]

# Get all unique keys
keys = {k for d in [*D1, *D2] for k in d}

# Initialize an empty dict
D3 = {x:[] for x in keys}

# sort to maintain order
D3 = dict(sorted(D3.items()))

#Iterate and extend
for x in [*D1, *D2]:
    for k,v in x.items():
        D3[k].append(v)

# NOTE: I do not recommend you convert a dictionary into a list of records.
# Nonetheless, here is how it would be done.
# To convert to a list
D3_list = [{k:v} for k,v in D3.items()]

print(D3_list)

# [{'k1': ['v01', 'v11']},
#  {'k2': ['v12']},
#  {'k3': ['v03']},
#  {'k4': ['v04', 'v14']}]

【讨论】:

    【解决方案3】:

    如果您打算使用实际的字典,而不是字典列表,这会更容易。

    D1 = dict(k1=1, k3=3, k4=4)
    D2 = dict(k1=11, k2=12, k4=14)
    

    没有一个简单的内置函数可以做到这一点,但setdefault 方法很接近。 它会尝试获取给定的密钥,但如果它不存在则创建它。

    D3 = {}
    for k, v in D1.items() | D2.items():
        D3.setdefault(k, set()).add(v)
    

    还有结果。

    {'k4': {4, 14}, 'k1': {1, 11}, 'k3': {3}, 'k2': {12}}
    

    这一切都假设顺序无关紧要,只是组合集合。

    【讨论】:

      【解决方案4】:

      将字典合并在一起的更通用的方法可能如下所示。 (回答类似的SO question

      def merge(combiner, dicts):
          new_dict = {}
          for d in dicts:
             for k, v in d.items():
                 if k in new_dict:
                     new_dict[k] = combiner(new_dict[k], v)
                 else:
                     new_dict[k] = v
          return new_dict
      
      x = {'a': 'A', 'b': 'B'}
      y = {'b': 'B', 'c': 'C'}
      z = {'a': 'A', 'd': 'D'}
      merge_dicts(combiner= lambda x, y: f'{x} AND {y}', dicts=(x,y,z))
      # {'a': 'A AND A', 'b': 'B AND B', 'c': 'C', 'd': 'D'}
      

      【讨论】:

        猜你喜欢
        • 2020-04-24
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-04-07
        • 1970-01-01
        • 2019-01-06
        • 2016-06-20
        • 1970-01-01
        相关资源
        最近更新 更多