我想深入合并2个字典,这两个字典在某个级别上具有相同键的一个或多个字典值。我怎样才能简单地合并那些内部词典?像“**”符号,但深度合并。
示例:
d1 = {"v1": "value1", "sub": {"sv1": "sub value 1"}}
d2 = {"v2": "value2", "sub": {"sv2": "sub value 2"}}
d3 = {**d1, **d2}
print(d3)
实际结果:
{'v1': 'value1', 'sub': {'sv2': 'sub value 2'}, 'v2': 'value2'}
期望的结果:
{'v1': 'value1',
'sub': {'sv1': 'sub value 1', 'sv2': 'sub value 2'},
'v2': 'value2'}
注意到子 - > sv1 - >子值1
这是一个简单的例子,而真实案例有几个级别的词典。此外,解决方案需要是通用的,因为词典的结构在高级中是未知的。
答案 0 :(得分:1)
您已经有了使用所有常用密钥创建 d3 的前三个步骤:
>>> d1 = {"v1": "value1", "sub": {"sv1": "sub value 1"}}
>>> d2 = {"v2": "value2", "sub": {"sv2": "sub value 2"}}
>>> d3 = {**d1, **d2} # initial merge of common keys
只需要一个后续步骤即可合并所有" sub"输入:
>>> for d in (d1, d2): # merge the "sub" entries
d3['sub'].update(d['sub'])
这给出了期望的结果:
>>> d3
{'v1': 'value1', 'sub': {'sv2': 'sub value 2', 'sv1': 'sub value 1'}, 'v2': 'value2'}
希望这会有所帮助: - )
答案 1 :(得分:1)
for python3:
d1 = {"v1": "value1", "sub": {"sv1": "sub value 1",'newsub':"value 2",'newsubdict':{'ok':'pssible','not_again':{'key1':'just checking'}}}}
d2 = {"v2": "value2", "sub": {"sv2": "sub value 2",'newsubdict':{'fine':'i am working','not_again':{'key2':'Am i right?'}}}}
from copy import deepcopy
d3 = deepcopy(d1)
def combine_key(d2,d3):
for key in d2.keys():
if(key in d3):
d3[key] =d2[key]
elif(isinstance(d3[key],dict)):
combine_key(d2[key],d3[key])
else:
d3[key].update(d2[key])
combine_key(d2,d3)
print(d3) #{'v1': 'value1', 'sub': {'sv1': 'sub value 1', 'newsub': 'value 2', 'newsubdict': {'ok': 'pssible', 'not_again': {'key1': 'just checking', 'key2': 'Am i right?'}, 'fine': 'i am working'}, 'sv2': 'sub value 2'}, 'v2': 'value2'}
答案 2 :(得分:1)
我最后写了这个:
import collections
import copy
def deep_dict_merge(dct1, dct2, override=True) -> dict:
"""
:param dct1: First dict to merge
:param dct2: Second dict to merge
:param override: if same key exists in both dictionaries, should override? otherwise ignore. (default=True)
:return: The merge dictionary
"""
merged = copy.deepcopy(dct1)
for k, v2 in dct2.items():
if k in merged:
v1 = merged[k]
if isinstance(v1, dict) and isinstance(v2, collections.Mapping):
merged[k] = deep_dict_merge(v1, v2, override)
elif isinstance(v1, list) and isinstance(v2, list):
merged[k] = v1 + v2
else:
if override:
merged[k] = copy.deepcopy(v2)
else:
merged[k] = copy.deepcopy(v2)
return merged