ChainMap是Python collections模塊中的一個成員,它用來將多個map組合到一起。Chain是鏈條的意思,字面意思就是把map串聯到一起。
問題的背景是我們有多個字典或者映射,想把它們合并成為一個單獨的映射,有人說可以用update進行合并,這樣做的問題就是新建了一個數據結構以致于當我們對原來的字典進行更改的時候不會同步。如果想建立一個同步的查詢方法,可以使用ChainMap
先看一下初步使用
from collections import ChainMap
a = {"x":1, "z":3}
b = {"y":2, "z":4}
c = ChainMap(a,b)
print(c)
print("x: {}, y: {}, z: {}".format(c["x"], c["y"], c["z"]))
輸出:
ChainMap({'x': 1, 'z': 3}, {'y': 2, 'z': 4})
x: 1, y: 2, z: 3
[Finished in 0.1s]
這是ChainMap最基本的使用,可以用來合并兩個或者更多個字典,當查詢的時候,從前往后依次查詢。
有一個注意點就是當對ChainMap進行修改的時候總是只會對第一個字典進行修改
In [6]: a = {"x":1, "z":3}
In [7]: b = {"y":2, "z":4}
In [8]: c = ChainMap(a, b)
In [9]: c
Out[9]: ChainMap({'z': 3, 'x': 1}, {'z': 4, 'y': 2})
In [10]: c["z"]
Out[10]: 3
In [11]: c["z"] = 4
In [12]: c
Out[12]: ChainMap({'z': 4, 'x': 1}, {'z': 4, 'y': 2})
In [13]: c.pop('z')
Out[13]: 4
In [14]: c
Out[14]: ChainMap({'x': 1}, {'z': 4, 'y': 2})
In [15]: del c["y"]
---------------------------------------------------------------------------
KeyError Traceback (most recent call last)
。。。。。。
KeyError: "Key not found in the first mapping: 'y'"
ChainMap和帶有作用域的值,諸如全局變量,局部變量之間工作的時候特別有效,
In [4]: a = ChainMap()
In [5]: a["x"]=1
In [6]: a
Out[6]: ChainMap({'x': 1})
In [7]: b = a.new_child()
In [8]: b
Out[8]: ChainMap({}, {'x': 1})
In [9]: b["x"] = 2
In [10]: b
Out[10]: ChainMap({'x': 2}, {'x': 1})
In [11]: b["y"] = 3
In [12]: b
Out[12]: ChainMap({'x': 2, 'y': 3}, {'x': 1})
In [13]: a
Out[13]: ChainMap({'x': 1})
In [14]: c = a.new_child()
In [15]: c
Out[15]: ChainMap({}, {'x': 1})
In [16]: c["x"]
Out[16]: 1
In [17]: c["y"] = 1
In [18]: c
Out[18]: ChainMap({'y': 1}, {'x': 1})
In [19]: d = c.parents()
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
in
()
----> 1 d = c.parents()
TypeError: 'ChainMap' object is not callable
In [20]: d = c.parents
In [21]: d
Out[21]: ChainMap({'x': 1})
In [22]: d is a
Out[22]: False
In [23]: d == a
Out[23]: True
從原理上面講,ChainMap實際上是把放入的字典存儲在一個隊列中,當進行字典的增加刪除等操作只會在第一個字典上進行,當進行查找的時候會依次查找,new_child()方法實質上是在列表的第一個元素前放入一個字典,默認是{},而parents是去掉了列表開頭的元素
In [24]: a = {"x":1, "z":3}
In [25]: b = {"y":2, "z":4}
In [26]: c = ChainMap(a,b)
In [27]: c
Out[27]: ChainMap({'x': 1, 'z': 3}, {'y': 2, 'z': 4})
In [28]: c.maps
Out[28]: [{'x': 1, 'z': 3}, {'y': 2, 'z': 4}]
In [29]: c.parents
Out[29]: ChainMap({'y': 2, 'z': 4})
In [30]: c.parents.maps
Out[30]: [{'y': 2, 'z': 4}]
In [31]: c.parents.parents
Out[31]: ChainMap({})
In [32]: c.parents.parents.parents
Out[32]: ChainMap({})
也正是因為底層是列表實現的,所以實際上ChainMap查詢的字典實際上還是原來的字典的引用
ChainMap文檔和示例:https://docs.python.org/3/library/collections.html#collections.ChainMap
以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持腳本之家。
更多文章、技術交流、商務合作、聯系博主
微信掃碼或搜索:z360901061
微信掃一掃加我為好友
QQ號聯系: 360901061
您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點擊下面給點支持吧,站長非常感激您!手機微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點擊微信右上角掃一掃功能,選擇支付二維碼完成支付。
【本文對您有幫助就好】元

