我有以下两个辞典
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条件。如何用一行或两行代码来做到这一点?
答案 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'
)的键在dict1
和dict2
中不相同,则可以删除进行一些安全检查,并让前两行合并最里面的字典:
>>> 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}}}
那只是为了好玩:太聪明时不要使用聪明的解决方案。