Dep*_*epa 4 python union merge dictionary
我有两个想要合并的词组:
a = {"name": "john",
"phone":"123123123",
"owns": {"cars": "Car 1", "motorbikes": "Motorbike 1"}}
b = {"name": "john",
"phone":"123",
"owns": {"cars": "Car 2"}}
Run Code Online (Sandbox Code Playgroud)
如果a
并且b
在同一嵌套级别上具有公共密钥,则结果应该是一个列表,其中包含两个值,该值被指定为共享密钥的值.
结果应如下所示:
{"name": "john",
"phone":["123123123","123"],
"owns": {"cars": ["Car 1", "Car 2"], "motorbikes": "Motorbike 1"}}
Run Code Online (Sandbox Code Playgroud)
使用a.update(b)
不起作用,因为它用共享值覆盖a
共享值b
,这样结果是这样的:
{'name': 'john', 'phone': '123', 'owns': {'cars': 'Car 2'}}
Run Code Online (Sandbox Code Playgroud)
目标是合并dicts而不覆盖,并保留与特定密钥相关的所有信息(在任何一个dicts中).
使用递归,您可以构建一个字典理解来完成它.
此解决方案还考虑到您可能希望稍后合并两个以上的词典,在这种情况下展平值列表.
def update_merge(d1, d2):
if isinstance(d1, dict) and isinstance(d2, dict):
# Unwrap d1 and d2 in new dictionary to keep non-shared keys with **d1, **d2
# Next unwrap a dict that treats shared keys
# If two keys have an equal value, we take that value as new value
# If the values are not equal, we recursively merge them
return {
**d1, **d2,
**{k: d1[k] if d1[k] == d2[k] else update_merge(d1[k], d2[k])
for k in {*d1} & {*d2}}
}
else:
# This case happens when values are merged
# It bundle values in a list, making sure
# to flatten them if they are already lists
return [
*(d1 if isinstance(d1, list) else [d1]),
*(d2 if isinstance(d2, list) else [d2])
]
Run Code Online (Sandbox Code Playgroud)
例:
a = {"name": "john", "phone":"123123123",
"owns": {"cars": "Car 1", "motorbikes": "Motorbike 1"}}
b = {"name": "john", "phone":"123", "owns": {"cars": "Car 2"}}
update_merge(a, b)
# {'name': 'john',
# 'phone': ['123123123', '123'],
# 'owns': {'cars': ['Car 1', 'Car 2'], 'motorbikes': 'Motorbike 1'}}
Run Code Online (Sandbox Code Playgroud)
合并了两个以上对象的示例:
a = {"name": "john"}
b = {"name": "jack"}
c = {"name": "joe"}
d = update_merge(a, b)
d = update_merge(d, c)
d # {'name': ['john', 'jack', 'joe']}
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
575 次 |
最近记录: |