1.20 å�ˆå¹¶å¤šä¸ªå—å…¸æˆ–æ˜ å°„Â¶
问题¶
现在有多个å—å…¸æˆ–è€…æ˜ å°„ï¼Œä½ æƒ³å°†å®ƒä»¬ä»Žé€»è¾‘ä¸Šå�ˆå¹¶ä¸ºä¸€ä¸ªå�•ä¸€çš„æ˜ å°„å�Žæ‰§è¡ŒæŸ�些æ“�作, 比如查找值或者检查æŸ�些键是å�¦å˜åœ¨ã€‚
解决方案¶
å�‡å¦‚ä½ æœ‰å¦‚ä¸‹ä¸¤ä¸ªå—å…¸:
a = {'x': 1, 'z': 3 }
b = {'y': 2, 'z': 4 }
现在å�‡è®¾ä½ 必须在两个å—兏䏿‰§è¡ŒæŸ¥æ‰¾æ“�作(比如先从 a 䏿‰¾ï¼Œå¦‚果找ä¸�到å†�在 b 䏿‰¾ï¼‰ã€‚
一个é�žå¸¸ç®€å�•的解决方案就是使用 collections 模å�—ä¸çš„ ChainMap 类。比如:
from collections import ChainMap
c = ChainMap(a,b)
print(c['x']) # Outputs 1 (from a)
print(c['y']) # Outputs 2 (from b)
print(c['z']) # Outputs 3 (from a)
讨论¶
一个 ChainMap 接å�—多个å—典并将它们在逻辑上å�˜ä¸ºä¸€ä¸ªå—典。
ç„¶å�Žï¼Œè¿™äº›å—典并ä¸�是真的å�ˆå¹¶åœ¨ä¸€èµ·äº†ï¼Œ ChainMap ç±»å�ªæ˜¯åœ¨å†…部创建了一个容纳这些å—典的列表
å¹¶é‡�新定义了一些常è§�çš„å—å…¸æ“�作æ�¥é��历这个列表。大部分å—å…¸æ“�作都是å�¯ä»¥æ£å¸¸ä½¿ç”¨çš„,比如:
>>> len(c)
3
>>> list(c.keys())
['x', 'y', 'z']
>>> list(c.values())
[1, 2, 3]
>>>
如果出现é‡�å¤�é”®ï¼Œé‚£ä¹ˆç¬¬ä¸€æ¬¡å‡ºçŽ°çš„æ˜ å°„å€¼ä¼šè¢«è¿”å›žã€‚
å› æ¤ï¼Œä¾‹å�程åº�ä¸çš„ c['z'] 总是会返回å—å…¸ a ä¸å¯¹åº”的值,而ä¸�是 b ä¸å¯¹åº”的值。
对于å—å…¸çš„æ›´æ–°æˆ–åˆ é™¤æ“�作总是影å“�的是列表ä¸ç¬¬ä¸€ä¸ªå—典。比如:
>>> c['z'] = 10
>>> c['w'] = 40
>>> del c['x']
>>> a
{'w': 40, 'z': 10}
>>> del c['y']
Traceback (most recent call last):
...
KeyError: "Key not found in the first mapping: 'y'"
>>>
ChainMap 对于编程è¯è¨€ä¸çš„作用范围å�˜é‡�(比如 globals , locals ç‰ï¼‰æ˜¯é�žå¸¸æœ‰ç”¨çš„。
事实上,有一些方法�以使它�得简�:
>>> values = ChainMap()
>>> values['x'] = 1
>>> # Add a new mapping
>>> values = values.new_child()
>>> values['x'] = 2
>>> # Add a new mapping
>>> values = values.new_child()
>>> values['x'] = 3
>>> values
ChainMap({'x': 3}, {'x': 2}, {'x': 1})
>>> values['x']
3
>>> # Discard last mapping
>>> values = values.parents
>>> values['x']
2
>>> # Discard last mapping
>>> values = values.parents
>>> values['x']
1
>>> values
ChainMap({'x': 1})
>>>
作为 ChainMap çš„æ›¿ä»£ï¼Œä½ å�¯èƒ½ä¼šè€ƒè™‘使用 update() 方法将两个å—å…¸å�ˆå¹¶ã€‚比如:
>>> a = {'x': 1, 'z': 3 }
>>> b = {'y': 2, 'z': 4 }
>>> merged = dict(b)
>>> merged.update(a)
>>> merged['x']
1
>>> merged['y']
2
>>> merged['z']
3
>>>
è¿™æ ·ä¹Ÿèƒ½è¡Œå¾—é€šï¼Œä½†æ˜¯å®ƒéœ€è¦�ä½ åˆ›å»ºä¸€ä¸ªå®Œå…¨ä¸�å�Œçš„å—å…¸å¯¹è±¡ï¼ˆæˆ–è€…æ˜¯ç ´å��现有å—典结构)。 å�Œæ—¶ï¼Œå¦‚果原å—å…¸å�šäº†æ›´æ–°ï¼Œè¿™ç§�改å�˜ä¸�会å��应到新的å�ˆå¹¶å—å…¸ä¸åŽ»ã€‚æ¯”å¦‚ï¼š
>>> a['x'] = 13
>>> merged['x']
1
ChainMap 使用原æ�¥çš„å—典,它自己ä¸�创建新的å—典。所以它并ä¸�会产生上é�¢æ‰€è¯´çš„结果,比如:
>>> a = {'x': 1, 'z': 3 }
>>> b = {'y': 2, 'z': 4 }
>>> merged = ChainMap(a, b)
>>> merged['x']
1
>>> a['x'] = 42
>>> merged['x'] # Notice change to merged dicts
42
>>>