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

在Python中合并具有相同键的字典层次结构,python,dictionary,Python,Dictionary,我有几个嵌套字典,第一级包含日期,第二级包含国家,每个国家都有一个数字列表 我想合并所有共享相同关键字的列表,即,要合并在一起的相同日期和相同国家,并形成最终词典 例如,这些词典中有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]}}

我有几个嵌套字典,第一级包含日期,第二级包含国家,每个国家都有一个数字列表

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

例如,这些词典中有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

请在问题中加入您的尝试。谢谢!当我尝试第二种选择时,结果是空的列表。啊,小错误:一个
dct
而不是
d
修复了它;-)