【问题标题】:Combining 2 dictionaries with common key将 2 个字典与公共键相结合
【发布时间】:2014-10-13 21:04:59
【问题描述】:

我有两个字典,需要合并其中相似键的值。这是一个例子:

dict1 = {'key1':[value11,value12,value13] , 'key2':[value21,value22,value23]}
dict2 = {'key1':[value14,value15] , 'key2':[value24,value25]}

我用过:

dict3 = {}
for key in (dict1.viewkeys() | dict2.keys()):
    if key in dict1: dict3.setdefault(key, []).append(dict1[key])
    if key in dict2: dict3.setdefault(key, []).append(dict2[key])

这给了我:

dict3 = {'key1':[[value11,value12,value13],[value14,value15]] , 'key2':[[value21,value22,value23],[value24,value25]]}

我想要的是一个简单的,比如:

期望的输出

 dict3 = {'key1':[value11,value12,value13,value14,value15] , 'key2':[value21,value22,value23,value24,value25]}

【问题讨论】:

  • 可能是一个简单的print {k:dict1.get(k, []) + dict2.get(k, []) for k in set(dict1.keys() + dict2.keys())} 就可以了
  • 你还想要平均值吗?
  • 是的,但其他人告诉我将其作为一个单独的问题提出
  • 大声笑,当你被要求编辑这个问题时,我已经回答了你删除的问题

标签: python python-2.7 dictionary


【解决方案1】:

你可以做的更简单,但如果你想使用你的代码,只需将append更改为extend

dict1 = {'key1':['value11','value12','value13'] , 'key2':['value21','value22','value23']}
dict2 = {'key1':['value14','value15'] , 'key2':['value24','value25']}

dict3 = {}
for key in (dict1.viewkeys() | dict2.keys()):
    if key in dict1: dict3.setdefault(key, []).extend(dict1[key])
    if key in dict2: dict3.setdefault(key, []).extend(dict2[key])

print dict3

输出:

{'key2': ['value21', 'value22', 'value23', 'value24', 'value25'], 'key1': ['value11', 'value12', 'value13', 'value14', 'value15']}

你可以阅读这个post关于附加到扩展的区别

【讨论】:

    【解决方案2】:

    您需要做的就是将append 修改为extend,这将添加列表的元素,而不是添加列表本身。有关appendextend 之间区别的更多详细信息,请参阅list docs

    dict1 = {'key1':['value11','value12','value13'] , 'key2':['value21','value22','value23']}
    dict2 = {'key1':['value14','value15'] , 'key2':['value24','value25']}
    
    dict3 = {}
    for key in set().union(dict1, dict2):
        if key in dict1: dict3.setdefault(key, []).extend(dict1[key])
        if key in dict2: dict3.setdefault(key, []).extend(dict2[key])
    
    print(dict3)
    # {'key2': ['value21', 'value22', 'value23', 'value24', 'value25'], 'key1': ['value11', 'value12', 'value13', 'value14', 'value15']}
    

    或者,您可以使用collections.defaultdict,默认设置为list,如下所示。

    from collections import defaultdict
    dict3 = defaultdict(list)
    
    for key in set().union(dict1, dict2):
      for dic in [dict1, dict2]:
        if key in dic:
          dict3[key] += dic[key]
    

    【讨论】:

    • defaultdict(list) 是做什么的??
    • defaultdict(list) 类似于在您的示例中使用 setdefault。基本上,如果密钥不在dict3 中,那么它会将值设置为默认[]。这种方式只是有点整洁(恕我直言)。
    • 我不喜欢除了 KeyError: pass - 这是对异常的糟糕管理。
    • @Ffisegydd 您可以使用条件(如果在 dic 中键入)而不是带有 pass 语句的异常管理。
    • 另外,我尝试测试您的答案,并且 (dict1.keys() | dict2.keys()) 在 python 2.7 中返回错误
    【解决方案3】:

    这是一个通用方法,您可以在该方法上传递任意数量的 dict 作为参数。

    >>> def mix_dict(*args):
           res = {}
           for d in args:
               if not isinstance(d, dict):
                   continue
               for k, v in d.iteritems():
                   res.setdefault(k, [])
                   if isinstance(v, list):
                       res[k].extend(v)
                   else:
                       res[k].append(v)
           return res
    >>> dict1 = {'key1':['value11','value12','value13'] , 'key2':['value21','value22','value23']}
    >>> dict2 = {'key1':['value14','value15'] , 'key2':['value24','value25']}
    >>> dict3 = mix_dict(dict1, dict2)
    >>> print dict3
    ... {'key1': ['value11', 'value12', 'value13', 'value14', 'value15'],
         'key2': ['value21', 'value22', 'value23', 'value24', 'value25']}
    

    【讨论】:

      【解决方案4】:

      这是另一种方法。

      您可以使用此功能支持将 N 个列表字典合并为单个列表字典:

      def mergeDoLs(*dicts):
          def flatten(LoL):
              return [e for l in LoL for e in l]
      
          rtr={k:[] for k in set(flatten(d.keys() for d in dicts))}
          for k, v in flatten(d.items() for d in dicts):
              rtr[k].extend(v)
          return rtr
      

      使用方法:

      >>> dict1 = {'key1':['value11','value12','value13'] , 'key2':['value21','value22','value23'], 'key3':[1]}
      >>> dict2 = {'key1':['value14','value15'] , 'key2':['value24','value25']}
      >>> dict3 = {'key3':[2]}
      >>> mergeDoLs(dict1, dict2, dict3) 
      {'key3': [1, 2], 'key2': ['value21', 'value22', 'value23', 'value24', 'value25'], 'key1': ['value11', 'value12', 'value13', 'value14', 'value15']}
      

      【讨论】:

        【解决方案5】:

        使用 dict.update() 合并两个字典键:dict1['key1'].update(dict2['key1'])

        【讨论】:

          猜你喜欢
          • 2011-06-03
          • 2017-12-12
          • 2019-11-29
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2019-11-11
          • 1970-01-01
          相关资源
          最近更新 更多