如何在一个表达式中合并两个复杂的词典?

2024-06-06 14:42:43 发布

您现在位置:Python中文网/ 问答频道 /正文

我有两本字典。你知道吗

第一个是:

modifiers_list = {
    'Body': {
        'Height': {
            'Tall': 1,
            'Short': 2
        }
    },
    'Neck': {
        'Tall': 3,
        'Short': 4
    }
}

第二个是

modifiers_list_Female = {
    'Body': {
        'Height': {
            'Extra Tall': 5,
            'Extra Short': 6
        }
    },
    'Neck': {
        'Neck 1': 7,
        'Neck 2': 8,
    }
}

预期结果应为:

{
    'Body': {
        'Height': {
            'Tall': 1,
            'Short': 2,
            'Height': {
                'Extra Tall': 5,
                'Extra Short': 6
            }
        },
        'Neck': {
            'Neck 1': 7,
            'Neck 2': 8,
            'Tall': 3,
            'Short': 4
        }
    }

我试过z = {**x, **y}然后

def merge_two_dicts(x, y):
    z = x.copy()   # start with x's keys and values
    z.update(y)    # modifies z with y's keys and values & returns None
    return z

但我不能得到我需要的执行结果。你知道吗


Tags: and字典defwithbodykeysextrafemale
2条回答

可以使用递归:

d1 = {'Body': {'Height': {'Tall': 1, 'Short': 2}}, 'Neck': {'Tall': 3, 'Short': 4}}
d2 = {'Body': {'Height': {'Extra Tall': 5, 'Extra Short': 6}}, 'Neck': {'Neck 1': 7, 'Neck 2': 8}}
def merge(d, _d):
  return {a:{**b, **_d[a]} if all(not isinstance(c, dict) for c in b.values()) \
             else merge(b, _d[a]) for a, b in d.items()}

import json
print(json.dumps(merge(d1, d2), indent=4))

输出:

 {
 "Body": {
    "Height": {
        "Tall": 1,
        "Short": 2,
        "Extra Tall": 5,
        "Extra Short": 6
     }
  },
  "Neck": {
    "Tall": 3,
    "Short": 4,
    "Neck 1": 7,
    "Neck 2": 8
   }
}

如果要在结果中包含第二个字典中的键:

def merge(d, _d):
   return {a:{**b, a:_d[a]} if all(not isinstance(c, dict) for c in b.values()) \
         else merge(b, _d[a]) for a, b in d.items()}

输出:

{
  "Body": {
    "Height": {
        "Tall": 1,
        "Short": 2,
        "Height": {
            "Extra Tall": 5,
            "Extra Short": 6
        }
    }
 },
 "Neck": {
    "Tall": 3,
    "Short": 4,
    "Neck": {
        "Neck 1": 7,
        "Neck 2": 8
     }
   }
}

基于Ajax1234答案,我创建了一个函数,该函数将字典合并到两个数据同步端:

def merge_v2(first_d, second_d):
    dictTemp = {}

    for a, b in second_d.items():
        if a not in first_d:
            print("Found key, that is not in first dictionary: " + str(a))
            dictTemp[a] = b

    for a, b in first_d.items():
        if all(not isinstance(c, dict) for c in b.values()):
            dictTemp[a] = {**b, **second_d[a]}
        else:
            if a in second_d:
                dictTemp[a] = merge_v2(b, second_d[a])
            else:
                pass
                dictTemp[a] = merge_v2(b, first_d[a])

    return dictTemp

示例:

modifiers_list = {
    'Body': {
        'Height': {
            'Tall': 1,
            'Short': 2
        }
    },
    'Neck': {
        'Tall': 3,
        'Short': 4
    }
}

modifiers_list_Female = {
    # 'Body': {
    #     'Height': {
    #         'Extra Tall': 5,
    #         'Extra Short': 6
    #     }
    # },
    'Neck': {
        'Neck 1': 7,
        'Neck 2': 8,
    },
    'Leg': {
        'Leg 1': 9,
        'Leg 2': 10,
    }
}

import json

print(json.dumps(merge_v2(modifiers_list, modifiers_list_Female), indent=4))

结果:

{
    "Leg": {
        "Leg 1": 9,
        "Leg 2": 10
    },
    "Body": {
        "Height": {
            "Tall": 1,
            "Short": 2
        }
    },
    "Neck": {
        "Tall": 3,
        "Short": 4,
        "Neck 1": 7,
        "Neck 2": 8
    }
}

这个代码的在线演示:https://repl.it/@ArthurKhusnutdi/pythonmergedictionaries

相关问题 更多 >