合并可变数量嵌套字典的通用函数

3

我想要创建一个通用的函数,用于合并Python中的n个嵌套字典。

我已经创建了一个合并三个字典的函数,但我希望将其推广到n个嵌套字典。

我创建的函数如下:

def mergedicts(dict1, dict2, dict3):
for k in set(dict1.keys()).union(dict2.keys()).union(dict3.keys()):
    if k in dict1 and k in dict2 and k in dict3 :
        if isinstance(dict1[k], dict) and isinstance(dict2[k], dict) and isinstance(dict3[k], dict):
            yield (k, dict(mergedicts(dict1[k], dict2[k], dict3[k])))
        else:
            # If one of the values is not a dict, you can't continue merging it.
            # Value from first and second dict are written in form of lists.
            yield (k, [dict1[k],dict2[k], dict3[k]])
            # Alternatively, replace this with exception raiser to alert you of value conflicts
    elif k in dict1:
        yield (k, dict1[k])
    elif k in dict2:
      yield(k,dict2[k])
    else:
        yield (k, dict3[k]

dict1 = {"canada":{'america':189,'asia':175,'europe': 186},
     "norway":{'australia': 123,'africa':124,'brazil':125}}
dict2=  {"canada":{'america':13,'asia':14,'europe': 15},
     "norway":{'australia': 17,'africa':18,'brazil':19}}
dict3=  {"canada":{'america':127,'asia':256,'europe': 16},
     "norway":{'australia': 17,'africa':18,'brazil':19}}
# After running the above function I have got this output
{'canada': {'europe': [186, 15, 16], 'america': [189, 13, 127], 'asia': [175, 14, 256]}, 'norway': {'australia': [123, 17, 17], 'brazil': [125, 19, 19], 'africa': [124, 18, 18]}}

有没有一种通用的方法可以合并Python中的 n 个嵌套字典。 (例如,我可能想以类似于上述方式合并20个嵌套字典,但是我的方法只允许合并三个嵌套字典。)


它们都有相同的键吗? - Freddy Mcloughlan
是的,密钥将是相同的。 - Noorulain Islam
2个回答

1

使用*args

def mergedicts(*args):
    # Keys are identical (comments), make base dict
    x = {
        "canada": {
            'america': [],
            'asia': [],
            'europe': []},
        "norway": {
            'australia': [],
            'africa': [],
            'brazil': []}
    }

    for d in args:
        for k, v in d.items():
            for ki, vi in v.items():
                x[k][ki].append(vi)

    return x

>>> mergedicts(dict1, dict2, dict3)
{'canada': {'america': [189, 13, 127],
            'asia': [175, 14, 256],
            'europe': [186, 15, 16]},
 'norway': {'africa': [124, 18, 18],
            'australia': [123, 17, 17],
            'brazil': [125, 19, 19]}}

如果您有随机密钥:
from copy import deepcopy


def mergedicts(*args):
    # If you have random keys. Uninon them all
    temp = deepcopy(args)
    x = temp[0]
    for d in temp[1:]:
        x | d

    # Set each value to be an empty list []

    for k, v in x.items():
        for ki in v:
            x[k][ki] = []

    for d in args:
        for k, v in d.items():
            for ki, vi in v.items():
                x[k][ki].append(vi)

    return x

注意这个第二个函数的可怕的时间复杂度。


1

您可以使用嵌套的for循环来生成所需的输出。

使用两个字典解析创建字典结构。然后,使用for循环来构建嵌套字典中的列表值:

data = [dict1, dict2, dict3]

result = {k: {ik: [] for ik in dict1[k].keys()} for k in dict1.keys()}

for entry in data:
    for key, value in entry.items():
        for inner_key, inner_value in value.items():
            result[key][inner_key].append(inner_value)
            
print(result)

这将输出:
{
'canada': {
  'america': [189, 13, 127],
  'asia': [175, 14, 256],
  'europe': [186, 15, 16]
 },
'norway': {
  'australia': [123, 17, 17],
  'africa': [124, 18, 18],
  'brazil': [125, 19, 19]
 }
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接