collections collections contain container data types. In python3 (3.4.3), there are some additions to the one in python2.7. Reference URL: http://docs.python.jp/3.4/library/collections.html The points added from python2.7 are as follows.
ChainMap: A dictionary-like class that creates a single view of multiple mappings UserDict: A dictionary object wrapper that simplifies dictionary subclassing UserList: List object wrapper that makes it easy to subclass lists UserString: A wrapper for string objects that makes it easy to subclass strings
User ~ is usually a class wrapper, so the explanation is omitted.
ChainMap
The code I wrote this time is on GitHub. (https://github.com/KodairaTomonori/Qiita/blob/master/default_module/collections/test_ChainMap.py) First, from the simple usage of ChainMap
test_ChainMap.py
import collections
import see
dict_a = dict(a=1, b=2, c=3)
dict_b = dict(x=10, y=11, z=12)
def get_name(arg_id, arg_values):
for key, value in arg_values.items():
if id(value) == arg_id: return key
return 'NotDefined'
def print_arguments(*args, arg_values):
for arg in args:
print(get_name(id(arg), arg_values) + ' : ' + repr(arg) )
chain_map = collections.ChainMap(dict_a, dict_b)
child = chain_map.new_child()
print('make_chain_maps')
print_arguments(chain_map, child, arg_values=locals() )
print('chain_map.maps: ' + repr(chain_map.maps) )
make_chain_maps chain_map : ChainMap({'b': 2, 'c': 3, 'a': 1}, {'z': 12, 'x': 10, 'y': 11}) child : ChainMap({}, {'b': 2, 'c': 3, 'a': 1}, {'z': 12, 'x': 10, 'y': 11}) chain_map.maps: [{'a': 1, 'c': 3, 'b': 2}, {'y': 11, 'z': 12, 'x': 10}]
As the name suggests, ChainMap
connectsmap (dictionaly)
.
You can keep each one as a dictionary, not just connect them.
So, as you can see from the output, there are separate dict_a and dict_b
.
If you do chain ['z'] and chain_map ['b']
, you will get '2 and 12', respectively.
When you use it, you can use it normally as one dict
.
By setting .new_child ()
, a new dict
will be created at the beginning.
By setting .maps
, ChainMap will be listed and returned.
Although not written in the code, you can use .items (), .keys (), .values ()
like normal dict
.
Looking at the reference URL, it seems that the search is from the front and the others are only from the front.
The search continues to search for the underlying mapping until the key is found. In contrast, write, update, and delete operate only on the first mapping.
Next, we will update.
update.py
child.update(d=4, a=0)
print('update_child_map')
print_arguments(chain_map, child, arg_values=locals() )
print()
chain_map.update(z=100)
print('update_parent_map')
print_arguments(chain_map, child, arg_values=locals() )
update_child_map chain_map : ChainMap({'a': 1, 'c': 3, 'b': 2}, {'y': 11, 'z': 12, 'x': 10}) child : ChainMap({'a': 0, 'd': 4}, {'a': 1, 'c': 3, 'b': 2}, {'y': 11, 'z': 12, 'x': 10}) update_parent_map chain_map : ChainMap({'a': 1, 'z': 100, 'c': 3, 'b': 2}, {'y': 11, 'z': 12, 'x': 10}) child : ChainMap({'a': 0, 'd': 4}, {'a': 1, 'z': 100, 'c': 3, 'b': 2}, {'y': 11, 'z': 12, 'x': 10})
Writing or updating to the child (leftmost dict) does not change the parent (dict other than the leftmost).
Also, if you change the parent, the change will be reflected in'child'.
The pointers of the common elements of chain_map and child
seem to point to the same place.
How to make one dictionary when something is messy and hard to see. You can simply enclose it in dict ().
merge.py
print('each_Chain')
print('chain_map:', dict(**chain_map) )
print('child :', dict(**child) )
each_Chain chain_map: {'x': 10, 'z': 100, 'c': 3, 'b': 2, 'a': 1, 'y': 11} child : {'x': 10, 'z': 100, 'c': 3, 'b': 2, 'a': 0, 'd': 4, 'y': 11}
ChainMap is convenient, but I can't think of any use for it.
This class can be used to simulate nested scopes and is useful for templating.
Although it is written in the reference URL, I do not understand well because it is only katakana. It seems that it can be used to check the update of weights when learning with NLP.
Recommended Posts