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

Python 如何在一个表达式中合并两个复杂的词典?,python,python-3.x,python-3.6,Python,Python 3.x,Python 3.6,我有两本字典 第一个是: modifiers_list = { 'Body': { 'Height': { 'Tall': 1, 'Short': 2 } }, 'Neck': { 'Tall': 3, 'Short': 4 } } 第二个是 modifiers_list_Female = { 'Body': { 'Height

我有两本字典

第一个是:

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
但我无法得到我需要的执行结果。

您可以使用递归:

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()}

输出:

 {
 "Body": {
    "Height": {
        "Tall": 1,
        "Short": 2,
        "Extra Tall": 5,
        "Extra Short": 6
     }
  },
  "Neck": {
    "Tall": 3,
    "Short": 4,
    "Neck 1": 7,
    "Neck 2": 8
   }
}
{
  "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
     }
   }
}
如果要在结果中包含第二个字典中的键:

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,
        "Extra Tall": 5,
        "Extra Short": 6
     }
  },
  "Neck": {
    "Tall": 3,
    "Short": 4,
    "Neck 1": 7,
    "Neck 2": 8
   }
}
{
  "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 answer,我创建了一个函数,该函数合并了字典,具有两个数据同步:

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
    }
}

此代码的在线演示:

为什么要以与颈部不同的方式合并
Body
?非常感谢,我的朋友@亚瑟很乐意帮忙!嗨,Ajax1234。我还有另一个例子,它抛出了一个异常——当第二个字典没有“Body”键时。在本例中,此代码抛出
Traceback(最后一次调用):文件“main.py”,第33行,打印(json.dumps(merge(modifiers\u list,modifiers\u list\u Female),indent=4))文件“main.py”,第30行,在merge-else-merge(b,\u-d[a])中为a,在d.items()中为b,在else-merge(b,\u-d[a])中为a,在d.items()中}KeyError:“Body”
@Arthur你能发布这些新数据和你想要的输出吗?