Collections module
This module implements target-specific containers to provide alternatives to Python's standard built-in containers dict, list, set, tuple.
- Counter: subclass of Dictionary, provides counting of hashable objects
- defaultdict: subclass of dictionary, provides a factory function that provides default values for dictionary lookups
- OrderedDict: a subclass of Dictionary that preserves the order in which they were added.
- namedtuple: factory function that creates a subclass of namedtuple
- deque: similar to the list container, the realization of the two ends of the fast add (append) and pop (pop)
- ChainMap: a dictionary-like container class that collects multiple mappings into a single view.
Counter
Counter is a dict subclass that is mainly used to count the frequency of the objects you access.
>>> import collections >>> # Counting the number of occurrences of a character ... ('hello world') Counter({'l': 3, 'o': 2, 'h': 1, 'e': 1, ' ': 1, 'w': 1, 'r': 1, 'd': 1}) >>> # Counting the number of words ... ('hello world hello lucy'.split()) Counter({'hello': 2, 'world': 1, 'lucy': 1})
Commonly used methods:
- elements(): return an iterator, the number of repetitions per element, if the count of an element is less than 1, it is ignored.
- most_common([n]): return a list providing the n most frequently accessed elements and counts
- subtract([iterable-or-mapping]): subtract elements from an iterable, input and output can be 0 or negative numbers
- update([iterable-or-mapping]): counts elements from an iterable or adds them from another mapped object (or counter).
>>> c = ('hello world hello lucy'.split()) >>> c Counter({'hello': 2, 'world': 1, 'lucy': 1}) >>> # Get the number of times the specified object has been accessed, you can also use the get method ... c['hello'] 2 >>> # View Elements ... list(()) ['hello', 'hello', 'world', 'lucy'] >>> c1 = ('hello world'.split()) >>> c2 = ('hello lucy'.split()) >>> c1 Counter({'hello': 1, 'world': 1}) >>> c2 Counter({'hello': 1, 'lucy': 1}) >>> # Append object, + or (c2) ... c1+c2 Counter({'hello': 2, 'world': 1, 'lucy': 1}) >>> # Reduce objects, - or (c2) ... c1-c2 Counter({'world': 1}) >>> # Clear ... () >>> c Counter()
defaultdict
Returns a new dictionary-like object. defaultdict is a subclass of the built-in dict class.
class ([default_factory[, ...]]) >>> d = () >>> d defaultdict(None, {}) >>> e = (str) >>> e defaultdict(<class 'str'>, {})
(for) instance
A typical use of defaultdict is to use one of the built-in types (e.g., str, int, list, or dict, etc.) as a default factory; these built-in types return the null type when called with no arguments.
>>> e = (str) >>> e defaultdict(<class 'str'>, {}) >>> e['hello'] '' >>> e defaultdict(<class 'str'>, {'hello': ''}) >>> # Error when ordinary dictionary is called with non-existent key ... e1 = {} >>> e1['hello'] Traceback (most recent call last): File "<stdin>", line 1, in <module> KeyError: 'hello'
Use int as default_factory
>>> fruit = (int) >>> fruit['apple'] = 2 >>> fruit defaultdict(<class 'int'>, {'apple': 2}) >>> fruit['banana'] # Returns 0 when there is no object 0 >>> fruit defaultdict(<class 'int'>, {'apple': 2, 'banana': 0})
Use list as default_factory
>>> s = [('yellow', 1), ('blue', 2), ('yellow', 3), ('blue', 4), ('red', 1)] >>> d = (list) >>> for k,v in s: ... d[k].append(v) ... >>> d defaultdict(<class 'list'>, {'yellow': [1, 3], 'blue': [2, 4], 'red': [1]}) >>> () dict_items([('yellow', [1, 3]), ('blue', [2, 4]), ('red', [1])]) >>> sorted(()) [('blue', [2, 4]), ('red', [1]), ('yellow', [1, 3])]
Use dict as default_factory
>>> nums = (dict) >>> nums[1] = {'one':1} >>> nums defaultdict(<class 'dict'>, {1: {'one': 1}}) >>> nums[2] {} >>> nums defaultdict(<class 'dict'>, {1: {'one': 1}, 2: {}})
Use set as default_factory
>>> types = (set) >>> types['Cell phone'].add('Huawei') >>> types['Cell phone'].add('Millet') >>> types['Display'].add('AOC') >>> types defaultdict(<class 'set'>, {'Cell phone': {'Huawei', 'Millet'}, 'Display': {'AOC'}})
OrderedDict
The order of keys in a Python dictionary is arbitrary; they are not controlled by the order in which they are added.
class provides dictionary objects that retain the order in which they were added >>> o = () >>> o['k1'] = 'v1' >>> o['k3'] = 'v3' >>> o['k2'] = 'v2' >>> o OrderedDict([('k1', 'v1'), ('k3', 'v3'), ('k2', 'v2')])
If you add a new value to an existing key, you keep the original key in place and overwrite the value.
>>> o['k1'] = 666 >>> o OrderedDict([('k1', 666), ('k3', 'v3'), ('k2', 'v2')]) >>> dict(o) {'k1': 666, 'k3': 'v3', 'k2': 'v2'}
namedtuple
Three ways to define a named tuple: the first argument is the constructor of the named tuple (as follows: Person1, Person2, Person3)
>>> P1 = ('Person1',['name','age','height']) >>> P2 = ('Person2','name,age,height') >>> P3 = ('Person3','name age height')
Instantiating Named Tuples
>>> lucy = P1('lucy',23,180) >>> lucy Person1(name='lucy', age=23, height=180) >>> jack = P2('jack',20,190) >>> jack Person2(name='jack', age=20, height=190) >>> # Call the instance directly via the instance name. attribute to invoke the 'lucy' >>> 23
deque
Returns a new bi-directional queue object, initialized from left to right (with method append()), created from iterable data. If iterable is not specified, the new queue is empty.
Queues support thread-safety with O(1) complexity for adding (append) or popping (pop) from both ends.
Although the list object supports similar operations, the overhead of fixed-length operations (pop(0), insert(0,v)) is optimized here.
If maxlen is not specified or is None, the deque can grow to any length. Otherwise, the deque is limited to the specified maximum length. Once a deque of limited length is full, the same number of items are popped out the other end when new items are added.
Methods of support:
- append(x): add x to right end
- appendleft(x): add x to left end
- clear(): clear all elements, length becomes 0
- copy(): creates a shallow copy.
- count(x): count the number of elements in the queue equal to x.
- extend(iterable): add elements of iterable to the right side of the queue
- extendleft(iterable): add the elements of iterable on the left side of the queue, note: when adding on the left side, the order of iterable parameters will be reversed.
- index(x[,start[,stop]]): returns the xth element (counting from start, before stop). Returns the first match and raises a ValueError if not found.
- insert(i,x): insert x at position i. Note: An IndexError is raised if the insertion causes a delimited deque to exceed the length maxlen.
- pop(): remove rightmost element
- popleft(): remove leftmost element
- remove(value): removes the first value found; no ValueError is thrown.
- reverse(): reverse the order of the deque. Returns None.
- maxlen: the maximum length of the queue, or None if not qualified.
>>> d = (maxlen=10) >>> d deque([], maxlen=10) >>> ('python') >>> [() for i in d] ['P', 'Y', 'T', 'H', 'O', 'N'] >>> ('e') >>> ('f') >>> ('g') >>> ('h') >>> d deque(['h', 'g', 'f', 'p', 'y', 't', 'h', 'o', 'n', 'e'], maxlen=10) >>> ('i') >>> d deque(['i', 'h', 'g', 'f', 'p', 'y', 't', 'h', 'o', 'n'], maxlen=10) >>> ('m') >>> d deque(['h', 'g', 'f', 'p', 'y', 't', 'h', 'o', 'n', 'm'], maxlen=10)
ChainMap
The background of the problem is that we have multiple dictionaries or mappings, and we want to merge them into a single mapping. Some people say that you can use update to do the merge, but the problem with this is that it creates a new data structure so that it won't be synchronized when we make changes to the original dictionary. If you want to create a synchronized query method, you can use ChainMap
Can be used to merge two or more dictionaries, when queried, in order from front to back. Simple to use:
>>> d1 = {'apple':1,'banana':2} >>> d2 = {'orange':2,'apple':3,'pike':1} >>> combined1 = (d1,d2) >>> combined2 = (d2,d1) >>> combined1 ChainMap({'apple': 1, 'banana': 2}, {'orange': 2, 'apple': 3, 'pike': 1}) >>> combined2 ChainMap({'orange': 2, 'apple': 3, 'pike': 1}, {'apple': 1, 'banana': 2}) >>> for k,v in (): ... print(k,v) ... orange 2 apple 1 pike 1 banana 2 >>> for k,v in (): ... print(k,v) ... apple 3 banana 2 orange 2 pike 1
One caveat is that when making changes to the ChainMap it will always only make changes to the first dictionary, and if that key does not exist in the first dictionary, it will be added.
>>> d1 = {'apple':1,'banana':2} >>> d2 = {'orange':2,'apple':3,'pike':1} >>> c = (d1,d2) >>> c ChainMap({'apple': 1, 'banana': 2}, {'orange': 2, 'apple': 3, 'pike': 1}) >>> c['apple'] 1 >>> c['apple'] = 2 >>> c ChainMap({'apple': 2, 'banana': 2}, {'orange': 2, 'apple': 3, 'pike': 1}) >>> c['pike'] 1 >>> c['pike'] = 3 >>> c ChainMap({'apple': 2, 'banana': 2, 'pike': 3}, {'orange': 2, 'apple': 3, 'pike': 1})
In principle, ChainMap actually stores the dictionaries in a queue, when adding or deleting dictionaries, it will only do so in the first dictionary, and when searching for them, it will search for them sequentially. new_child() method essentially puts a dictionary in front of the first element of the list, which is {} by default, and parents is the first element of the list, and parents is the first element of the list, which is {}, and parents is the first element of the list, which is {}, and parents is the first element of the list. element at the beginning of the list.
>>> a = () >>> a['x'] = 1 >>> a ChainMap({'x': 1}) >>> b = a.new_child() >>> b ChainMap({}, {'x': 1}) >>> b['x'] = 2 >>> b ChainMap({'x': 2}, {'x': 1}) >>> b['y'] = 3 >>> b ChainMap({'x': 2, 'y': 3}, {'x': 1}) >>> a ChainMap({'x': 1}) >>> c = a.new_child() >>> c ChainMap({}, {'x': 1}) >>> c['x'] = 1 >>> c['y'] = 1 >>> c ChainMap({'x': 1, 'y': 1}, {'x': 1}) >>> d = >>> d ChainMap({'x': 1}) >>> d is a False >>> d == a True
>>> a = {'x':1,'z':3} >>> b = {'y':2,'z':4} >>> c = (a,b) >>> c ChainMap({'x': 1, 'z': 3}, {'y': 2, 'z': 4}) >>> [{'x': 1, 'z': 3}, {'y': 2, 'z': 4}] >>> ChainMap({'y': 2, 'z': 4}) >>> [{'y': 2, 'z': 4}] >>> ChainMap({}) >>> ChainMap({})
to this article on the use of Python collections module is introduced to this article, more related Python collections module content, please search for my previous posts or continue to browse the following related articles I hope you will support me in the future!