在Python中合并具有相同密钥的两个字典

时间:2019-04-23 02:52:35

标签: python python-3.x dictionary

我有以下两个辞典

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循环和if条件。如何用一行或两行代码来做到这一点?

2 个答案:

答案 0 :(得分:2)

使用副作用从多个for循环逻辑派生的不良单线将是

url = 'https://finance.yahoo.com/quote/SPY'
result = requests.get(url)

c = result.content
html = BeautifulSoup(c, 'html.parser')
scripts = html.find_all('script')

sl =[]
for s in scripts:

     sl.append(s)

s = (sl[-3])
s = s.contents
s = str(s)
s = s[119:-16]
s = json.dumps(s)
json_data = json.loads(s)

输出将是。

{v4.update(v3) for v1 in dict1.values() for v2 in dict2.values() for v3 in v1.values() for v4 in v2.values()}

如您所见,该代码不是很可读,但是可以完成工作

答案 1 :(得分:1)

通用方法

要将两个字典与嵌套字典合并,必须执行树遍历(例如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 中不相同,则可以删除进行一些安全检查,并让前两行合并最里面的字典:

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

那只是为了好玩:太聪明时不要使用聪明的解决方案。