合并具有相同键的2个字典

11
我有两个字典,需要将它们中相似键的值合并。以下是一个示例:
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]}

2
可能一个简单的 print {k:dict1.get(k, []) + dict2.get(k, []) for k in set(dict1.keys() + dict2.keys())} 就行了。 - njzk2
你还需要平均值吗? - Padraic Cunningham
是的,但其他人告诉我应该将其作为一个单独的问题提出。 - Hypothetical Ninja
当你编辑这个问题的时候,我已经回答了你删除的那个问题。 - Padraic Cunningham
这是另一个问题的链接:http://stackoverflow.com/questions/25408370/combine-dictionaries-with-aggregate-values-for-similar-keys-python。 - Hypothetical Ninja
5个回答

3
你只需要修改appendextend,这将添加列表的元素而不是添加列表本身。请参阅list文档了解有关appendextend之间差异的更多详细信息。
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']}

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

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)是什么意思? - Hypothetical Ninja
defaultdict(list)类似于在示例中使用setdefault。基本上,如果键尚未存在于dict3中,则它将将值设置为默认的[]。这种方式只是有点更整洁(在我看来)。 - Ffisegydd
我不喜欢 except KeyError: pass - 这是异常处理的糟糕管理。 - Quentin THEURET
@Ffisegydd,你可以使用条件语句(if key in dic)而不是通过pass语句进行异常处理。 - Quentin THEURET
另外,我尝试测试你的答案,但在Python 2.7中(dict1.keys() | dict2.keys())会返回一个错误。 - Quentin THEURET
@QuentinTHEURET,虽然我不同意你的观点,但我已经修改了它,因为对于那些不太熟悉try...except...循环的人来说,这样可能更易读。是的,我将其更改为Python 3.4的keys(这是我使用的版本)。 - Ffisegydd

3

这是一个通用的方法,您可以将多个字典作为参数传递。

>>> 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']}

2
您可以使用更简单的方法,但如果您想使用您的代码,请将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

1

这里有另一种方法来完成这个任务。

你可以使用这个函数支持将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']}

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

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接