Thanks to @naivepredictor's comment, I find that my question is ambiguous and equivocal.
I want to merge two nested and deep dictories.It is similar to How to merge two dictionaries in a single expression?, but different to it, I want to merge two values to one list when merging. It is similar to Merge two dictionaries and keep the values for duplicate keys in Python, but dict in here is nested and deep. as follows: For example:
dic_a = {
'a1': {'a2': {'a3': 4}},
'a11': {'a2': {'a3': 4}},
'a111': {'a2': {'a3': 4}},
'a1111': {'a2': {'a3': 4}}
}
dic_b = {
'a1': {'a2': {'a3': [4, 9]}},
'b1': {'b2': {'b3': 99}},
'b11': {'b2': {'b3': 99}},
'b111': {'b2': {'b3': 99}},
'b1111': {'b2': {'b3': 99}}
}
print(merged_dict)
"""
{'a1': {'a2': {'a3': [4, 4, 9]}},
'a11': {'a2': {'a3': 4}},
'a111': {'a2': {'a3': 4}},
'a1111': {'a2': {'a3': 4}},
'b1': {'b2': {'b3': 99}},
'b11': {'b2': {'b3': 99}},
'b111': {'b2': {'b3': 99}},
'b1111': {'b2': {'b3': 99}}}
"""
I have implemented an merge_dicts
with recursion. as follows.
from copy import deepcopy
def _add_value_to_list(value, lis):
if value:
if isinstance(value, list):
lis.extend(value)
else:
lis.append(value)
else:
pass
def _merge_value(value_a, value_b):
merged_value = []
_add_value_to_list(value_a, merged_value)
_add_value_to_list(value_b, merged_value)
return merged_value
def _recursion_merge_dict(new_dic, dic_a, dic_b):
if not dic_a or not dic_b:
return new_dic
else:
if isinstance(new_dic, dict):
for k, v in new_dic.items():
new_dic[k] = _recursion_merge_dict(v, dic_a.get(k, {}), dic_b.get(k, {}))
return new_dic
else:
return _merge_value(dic_a, dic_b)
def merge_dicts(dic_a, dic_b):
new_dic = deepcopy(dic_a)
new_dic.update(dic_b)
return _recursion_merge_dict(new_dic, dic_a, dic_b)
But it run slowly, I need a more quick one. Thank you.
The leaf values of dictionaries needed to be merged just belong to list
or unicode
.