我正在寻找一种将多个字典相互合并的方法,这些字典也包含嵌套的字典。嵌套字典的数量不是静态的,而是动态的。
最后的dict应该包含所有dict及其值的总和:
COUNTRY1 = {'a': {'X': 10, 'Y': 18, 'Z': 17}, 'b': {'AA':{'AAx':45,'AAy':22},'BB':{'BBx':45,'BBy':22}}, 'c': 100}
COUNTRY2 = {'a': {'U': 12, 'V': 34, 'W': 23}, 'b': {'AA':{'AAz':23,'AAa':26},'BB':{'BBz':11,'BBa':15}}, 'c': 115}
COUNTRY3 = {'a': {'Y': 15, 'Z': 14, 'X': 12}, 'b': {'AA':{'AAx':45,'AAz':22},'BB':{'BBy':45,'BBz':22}}, 'c': 232}
# After merging the dictionaries the result should look like:
ALL
>>> {'a': {'X': 22, 'Y': 33, 'Z': 31, 'U': 12, 'V': 34, 'W': 23}, 'b': {'AA':{'AAx':90,'AAy':22,'AAz':45,'AAa':26},'BB':{'BBx':45,'BBy':67, 'BBz':33,'BBa':15}}, 'c': 447}
我尝试了以下代码,该代码允许嵌套字典最多为3个嵌套字典。不幸的是,代码没有达到我的期望。因此,它看起来不是很干净,我觉得可以通过递归函数来完成,但是我找不到解决方法。
COUNTRIES = ['COUNTRY1','COUNTRY2', 'COUNTRY3']
ALL = {}
for COUNTRY_CODE in COUNTRIES:
COUNTRY = pickle.load(open(COUNTRY_CODE+".p", "rb"))
keys = COUNTRY.keys()
for key in keys:
try:
keys2 = COUNTRY[key].keys()
print(key, keys2)
for key2 in keys2:
try:
keys3 = COUNTRY[key][key2].keys()
print(key2, keys3)
for key3 in keys3:
try:
keys4 = COUNTRY[key][key2][key3].keys()
print(key3, keys4)
except:
print(key3, "NO KEY3")
if not key3 in ALL[key][key2]:
ALL[key][key2][key3] = COUNTRY[key][key2][key3]
else:
ALL[key][key2][key3] =+ COUNTRY[key][key2][key3]
except:
print(key2, "NO KEY2")
if not key2 in ALL[key]:
ALL[key][key2] = COUNTRY[key][key2]
else:
ALL[key][key2] =+ COUNTRY[key][key2]
except:
print(key, "NO KEY")
if not key in ALL:
ALL[key] = COUNTRY[key]
else:
ALL[key] =+ COUNTRY[key]
print(ALL)
答案 0 :(得分:3)
问题是您需要根据值的类型确定如何处理字典键。基本思想是:
这很容易理解:
def add_dicts(d1, d2):
def sum(v1, v2):
if v2 is None:
return v1
try:
return v1 + v2
except TypeError:
return add_dicts(v1, v2)
result = d2.copy()
result.update({k: sum(v, d2.get(k)) for k, v in d1.items()})
return result
该副本可确保将d2
中所有不在d1
中的键简单地复制过来。
您现在可以总结如下:
ALL = add_dicts(add_dicts(COUNTRY1, COUNTRY2), COUNTRY3)
通常,您可以使用functools.reduce
来执行不确定数量的字典:
dicts = [COUNTRY1, COUNTRY2, COUNTRY3]
ALL = reduce(add_dicts, dicts)
答案 1 :(得分:2)
执行以下两个功能:
def cal_sum(lst):
final_dict = dict()
for l in lst:
sum(final_dict,l)
return final_dict
def sum(final_dict,iter_dict):
for k, v in iter_dict.items():
if isinstance(v, dict):
sum(final_dict.setdefault(k, dict()), v)
elif isinstance(v, int):
final_dict[k] = final_dict.get(k, 0) + v
按如下所示调用上面的代码会产生所需的输出:
>>> print(cal_sum([COUNTRY1, COUNTRY2, COUNTRY3]))
{'a': {'U': 12, 'W': 23, 'V': 34, 'Y': 33, 'X': 22, 'Z': 31}, 'c': 447, 'b': {'AA': {'AAa': 26, 'AAy': 22, 'AAx': 90, 'AAz': 45}, 'BB': {'BBa': 15, 'BBz': 33, 'BBy': 67, 'BBx': 45}}}