如何在一个表达式中合并两个复杂的字典?
How to merge two complex dictionaries in a single expression?
我有两本词典。
第一个是:
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()}
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
我有两本词典。
第一个是:
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()}
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