Detailed usage and instructions for python ChainMap
- 2021-06-28 12:59:26
- OfStack
ChainMap is a member of the Python collections module that is used to group multiple maps together.Chain means chain, literally linking map together.
The background of the problem is that we have multiple dictionaries or maps and want to merge them into a single map. Some people say that update can be used for merging. The problem with this is that we have created a new data structure that won't synchronize when we make changes to the original dictionary.If you want to create a synchronous query method, you can use ChainMap
First look at 1 initial use
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"]))
Output:
ChainMap({'x': 1, 'z': 3}, {'y': 2, 'z': 4})
x: 1, y: 2, z: 3
[Finished in 0.1s]
This is the most basic use of ChainMap, which can be used to merge two or more dictionaries and query one after the other when querying.
One caveat is that when ChainMap is modified, only the first dictionary is always modified
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 and scoped values, such as global variables and local variables, work particularly well.
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)
<ipython-input-19-dc4debb7ca3b> in <module>()
----> 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
In principle, ChainMap actually stores the dictionary in a queue. When a dictionary is added or deleted, operations such as adding or deleting dictionaries only occur on the first dictionary. When a dictionary is searched, it looks in turn, new_The child() method essentially puts a dictionary before the first element of the list, defaulting to {}, while parents is the element that removes the beginning of the list
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({})
It is also because the bottom level is a list implementation that the dictionary queried by ChainMap is actually a reference to the original dictionary
ChainMap documentation and examples: https://docs.python.org/3/library/collections.html#collections.ChainMap