在Python中合并具有相同键的字典的层次结构



我有几个嵌套字典,其中包含第一级的日期、第二级的国家,以及每个国家的数字列表。

我想合并所有共享相同关键字的列表,即,将相同的日期和相同的国家合并在一起,形成最终的词典。

例如,其中3个字典可能看起来像:

a = {
2018-01-01: {'China': [1,3,5,7,8], 
'Japan': [1,2,3,4,5]},
2018-02-01: {'China': [1,2,3,4,5], 
'Spain': [1,2,3,4,5]}}
b = {2018-02-01: {'China': [2,4,6,8,10], 
'Germany': [1,3,6,9]}}
c = {2018-02-01: {'France': [1,2,3,4,5], 
'Spain': [2,3,1,4,5]}}

合并后的名单如下:

merged_list = {
2018-01-01: {'China': [1,3,5,7,8], 
'Japan': [1,2,3,4,5]}, 
2018-02-01: {'Spain': [1,2,3,4,5,2,3,1,4,5], 
'China': [1,2,3,4,5,2,4,6,8,10], 
'Germany': [1,3,6,9], 
'France': [1,2,3,4,5]}}

我真的不知道该怎么办。我尝试过做以下操作,但它只是合并日期并覆盖每个日期内的值:

merged_list = {**a, **b, **c}
returns 
{2018-01-01: {'China': [1,3,5,7,8], 'Japan': [1,2,3,4,5]},
2018-02-01: {'France': [1,2,3,4,5], 'Spain': [2,3,1,4,5]}}

以下递归函数将合并这样的数据结构:

def merge(*dcts):
d = {}
for key in set(k for dct in dcts for k in dct.keys()):
try:
d[key] = sum((dct.get(key, []) for dct in dcts), [])
except TypeError:
d[key] = merge(*(dct.get(key, {}) for dct in dcts))
return d
>>> merge(a, b, c)
{'2018-01-01': {'China': [1, 3, 5, 7, 8], 
'Japan': [1, 2, 3, 4, 5]},
'2018-02-01': {'China': [1, 2, 3, 4, 5, 2, 4, 6, 8, 10],
'France': [1, 2, 3, 4, 5],
'Germany': [1, 3, 6, 9],
'Spain': [1, 2, 3, 4, 5, 2, 3, 1, 4, 5]}}

或者,您可以使用collections.defaultdict使其可读性更强:

from collections import defaultdict
def merge(*dcts):
d = defaultdict(lambda: defaultdict(list))
for dct in dcts:
for date in dct:
for country in dct[date]:
d[date][country] += dct[date][country]
return d

最新更新