在很多场景中,需要用到合并复杂字典的功能,即字典的某些value是字典,此字典的某些value还是字典。
此函数利用递归函数,实现了任意层级value问字典的合并功能,相同的键值(非dict)以dict_2优先。
def merge(dict_1, dict_2):
print(f"merge({dict_1}, {dict_2})")
result = dict_1.copy()
for k, v in dict_1.items():
if isinstance(v, dict) and k in dict_2:
assert isinstance(dict_2[k], dict), f"For key {k}, value in dict_1 is dict, but is not in dict_2."
merged_value = merge(dict_1[k], dict_2.pop(k))
result[k] = merged_value
elif k in dict_2:
result[k] = dict_2.pop(k)
else:
pass
result.update(dict_2)
return result
本函数只对dict类型的值进行合并,其他类型(str, int, list, tuple等)仅仅进行覆盖。个人认为,这样也符合大多数场景的需求。作者本人是因为要合并深度学习框架的配置文件而写的这个函数,在此场景是不需要合并list,tuple的。如有其他需求可以更改merge函数。
测试如下
dict1 = {'a': 10, 'b': {'ba': {"d": 99, "dd": 88}, 'bb': 4}}
dict2 = {'b': {'ba': {"d": 99, "ee": 77}, "bc": 222}, 'c': 4}
print(merge(dict1, dict2))
输出结果如下,正确。暂未进行更多测试用例测试。
merge({'a': 10, 'b': {'ba': {'d': 99, 'dd': 88}, 'bb': 4}}, {'b': {'ba': {'d': 99, 'ee': 77}, 'bc': 222}, 'c': 4})
merge({'ba': {'d': 99, 'dd': 88}, 'bb': 4}, {'ba': {'d': 99, 'ee': 77}, 'bc': 222})
merge({'d': 99, 'dd': 88}, {'d': 99, 'ee': 77})
{'a': 10, 'b': {'ba': {'d': 99, 'dd': 88, 'ee': 77}, 'bb': 4, 'bc': 222}, 'c': 4}