合并多個(gè)字典或映射
ChainMap
假設(shè)有多個(gè)字典或者映射署浩,需求是將這些字典或者映射扮休,從邏輯上合并為一個(gè)單一的映射后執(zhí)行其他操作蔗怠,例如查找值或者檢查某些鍵是否存在。
假如有如下兩個(gè)字典:
>>> a = {'x': 1, 'z':3}
>>> b = {'y': 2, 'z': 4}
假設(shè)現(xiàn)在的需求是在兩個(gè)字典中執(zhí)行查詢操作它匕,先在字典 a
中查找刀脏,若查詢無結(jié)果,再在 b
中查找超凳。這里有個(gè)解決方案就是使用 collections
模塊中提供的 ChainMap
類愈污。示例如下:
>>> from collections import ChainMap
>>> c = ChainMap(a, b)
>>> c['x'] # 從 a 中輸出
1
>>> c['y'] # 從 b 中輸出
2
>>> c['z'] # 從 a 中輸出
3
ChainMap
作用是將多個(gè)字典或者其他映射組合在一起,創(chuàng)建一個(gè)單獨(dú)的可更新的視圖轮傍。這里的意思是暂雹,原多個(gè)字典并非真的合并在一起,是 ChainMap
類在內(nèi)部創(chuàng)建一個(gè)容納這些字典列表创夜,同時(shí)重新定義一些常見的字典操作來遍歷這個(gè)列表杭跪。以下是使用 ChainMap
后的一部分字典操作:
>>> len(c)
3
>>> list(c.keys())
['z', 'y', 'x']
>>> list(c.values())
[3, 2, 1]
這里特別提及下,如果出現(xiàn)重復(fù)鍵驰吓,會(huì)返回第一次出現(xiàn)的映射值涧尿。因此,上面例子中檬贰, c['z']
返回的值總是對(duì)應(yīng)字典 a
姑廉,而不是字典 b
。
同時(shí)翁涤,對(duì)于字典的更像或者刪除操作也同樣是影響列表中的第一個(gè)字典桥言。示例如下:
>>> c['z'] = 10
>>> c['w'] = 60
>>> del c['x']
>>> a
{'z': 10, 'w': 60}
>>> del c['y']
Traceback (most recent call last):
...
KeyError: "Key not found in the first mapping: 'y'"
new_child() 和 parents
ChainMap
還有個(gè) new_child
方法和 parents
屬性。
下面是兩者的一些使用方法:
>>> values = ChainMap()
>>> values['x'] = 1
>>> # 添加一個(gè)新的映射
... values = values.new_child()
>>> values['x'] = 2
>>> # 添加一個(gè)新的映射
... values = values.new_child()
>>> values['x'] = 3
>>> values
ChainMap({'x': 3}, {'x': 2}, {'x': 1})
>>> values['x']
3
>>> # 丟棄映射
... values = values.parents
>>> values['x']
2
>>> values = values.parents
>>> values['x']
1
>>> values
ChainMap({'x': 1})
從上面的例子中可以看到葵礼,new_child()
方法返回一個(gè)新的 ChainMap
類号阿,包含一個(gè)新映射,后面跟隨當(dāng)前實(shí)例的全部映射鸳粉。這個(gè)方法用于創(chuàng)建子上下文扔涧,不改變?nèi)魏胃赣成涞闹怠?/p>
parents
屬性返回一個(gè)新的 ChainMap
包含所有的當(dāng)前實(shí)例的映射,除了第一個(gè)届谈。這樣可以在搜索的時(shí)候跳過第一個(gè)映射枯夜。
作為 ChainMap
的替代,可以考慮 update()
方法將兩個(gè)字典合并疼约,示例如下:
>>> 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
>>>
update()
方法同樣能夠?qū)崿F(xiàn)需求卤档,但是蝙泼,它需要新建一個(gè)完全不同的字典對(duì)象(或者破壞現(xiàn)有的字典結(jié)構(gòu))程剥,還有一點(diǎn)是,原字典所做的更像,不會(huì)反應(yīng)到新的字典中织鲸。示例如下:
>>> a['x'] = 13
>>> merged['x']
1
對(duì)字典 a
中的 x
進(jìn)行更改舔腾,合并后的字典并沒有發(fā)生改變。
ChainMap
使用原來的字典搂擦,它自己不創(chuàng)建新的字典稳诚。所以不會(huì)出現(xiàn)上面的情況,示例如下:
>>> a = {'x': 1, 'z': 3}
>>> b = {'y': 2, 'z': 4}
>>> merged = ChainMap(a, b)
>>> merged['x']
1
>>> a['x'] = 13
>>> merged['x'] # 這里可以注意到用 ChainMap 合并的字典瀑踢,值同樣發(fā)生了改變
13
以上就是本篇的主要內(nèi)容扳还。