繁体   English   中英

合并具有相同键的python中的两个dict

[英]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' )的键在dict1dict2中从不相同, 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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM