[英]merge two dict in python having the same key
我有以下两个词
dict1 = {'roll':{1:{'abc':100},2:{'abc':200},4:{'abc':900}},'no_roll':{}}
dict2 = {'roll':{1:{'cde':500},2:{'cde':600}},'no_roll':{4:{'cde':500}}}
我想合并得到一个像这样的字典,
final_dict = {'roll': {1: {'abc': 100,'cde': 500},2:{'abc': 200,'cde': 600},4:{'abc':900}},'no_roll': {4:{'cde':500}}}
我能够做多个for循环和条件。我怎么能用一行或两行代码呢?
从使用副作用的多个for循环逻辑派生的坏单行将是。
{v4.update(v3) for v1 in dict1.values() for v2 in dict2.values() for v3 in v1.values() for v4 in v2.values()}
输出将是。
print(dict2)
#{'roll': {1: {'cde': 500, 'abc': 200}, 2: {'cbd': 600, 'abc': 200}},
#'no_roll': {}}
正如您所看到的,代码不是很易读,但可以完成工作
要将两个dicts与嵌套dicts合并,您必须执行树遍历(例如DFS):
>>> d1 = {'roll':{1:{'abc':100},2:{'abc':200},4:{'abc':900}},'no_roll':{}}
>>> d2 = {'roll':{1:{'cde':500},2:{'cde':600}},'no_roll':{4:{'cde':500}}}
>>> def merge(d1, d2):
... d = {k: d1[k] for k in set(d1) - set(d2)}
... d.update({k: d2[k] for k in set(d2) - set(d1)})
... for k in set(d2) & set(d1):
... assert isinstance(d1[k], dict) == isinstance(d2[k], dict), "inconsistent dicts"
... if isinstance(d1[k], dict):
... d[k] = merge(d1[k], d2[k])
... else:
... d[k] = d2[k] # keep only the second value, but we can keep a list if needed
... return d
...
>>> merge(d1, d2)
{'roll': {4: {'abc': 900}, 1: {'abc': 100, 'cde': 500}, 2: {'abc': 200, 'cde': 600}}, 'no_roll': {4: {'cde': 500}}}
>>> merge(d1, {'roll':400})
Traceback (most recent call last):
...
AssertionError: inconsistent dicts
如果终端值( 'abc'
和'cde'
)的键在dict1
和dict2
中从不相同, dict1
可以删除一些安全检查,并让前两行合并最里面的dicts:
>>> def merge2(d1, d2):
... d = {k: d1[k] for k in set(d1) - set(d2)}
... d.update({k: d2[k] for k in set(d2) - set(d1)})
... for k in set(d2) & set(d1):
... d[k] = merge(d1[k], d2[k])
... return d
...
>>> merge2(d1, d2)
{'roll': {4: {'abc': 900}, 1: {'abc': 100, 'cde': 500}, 2: {'abc': 200, 'cde': 600}}, 'no_roll': {4: {'cde': 500}}}
如果您想以两行执行此操作:
>>> merge3 = lambda d1, d2: {**{k: d1[k] for k in set(d1) - set(d2)}, **{k: d2[k] for k in set(d2) - set(d1)}, **{k: merge3(d1[k], d2[k]) for k in set(d2) & set(d1)}}
>>> merge3(d1, d2)
{'roll': {4: {'abc': 900}, 1: {'abc': 100, 'cde': 500}, 2: {'abc': 200, 'cde': 600}}, 'no_roll': {4: {'cde': 500}}}
使用Python 3.8,一行:
>>> (merge4 := lambda d1, d2: {**{k: d1[k] for k in set(d1) - set(d2)}, **{k: d2[k] for k in set(d2) - set(d1)}, **{k: merge4(d1[k], d2[k]) for k in set(d2) & set(d1)}})(d1, d2)
{'roll': {4: {'abc': 900}, 1: {'abc': 100, 'cde': 500}, 2: {'abc': 200, 'cde': 600}}, 'no_roll': {4: {'cde': 500}}}
这只是为了好玩:当他们太聪明时,不要使用聪明的解决方案。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.