The collections module in Python contains some container data types.
import collections [x for x in dir(collections) if not x.startswith('_')] # result: ['ChainMap', 'Counter', 'OrderedDict', 'UserDict', 'UserList', 'UserString', 'abc', 'defaultdict', 'deque', 'namedtuple']
1. collections.ChainMap() [Search multiple dictionaries]
Search multiple dictionaries in the order in which they appear.
m=collections.ChainMap(Dictionary 1, Dictionary 2, Dictionary 3,…): manages multiple dictionaries, provides context containers, and can be viewed as a stack.
m.maps: List of mappings. A list of dictionaries. The value searched is the first value in the map found in order. The order can be changed.
import collections a = {"a":"A","b":"B"} b = {"c":"C","b":"D"} m = collections.ChainMap(a,b) m # Result: ChainMap({'a': 'A', 'b': 'B'}, {'c': 'C', 'b': 'D'}) # Mapping list m.maps # Result: [{'a': 'A', 'b': 'B'}, {'c': 'C', 'b': 'D'}] # Get the value of the key and return the value in the first map found in order m["a"] # Result: 'A' m["b"] # Result: 'B' m["c"] # Result: 'C' list(m.keys()) # Result: ['c', 'b', 'a'] list(m.values()) # Result: ['C', 'B', 'A'] list(m.items()) # Result: [('c', 'C'), ('b', 'B'), ('a', 'A')] # Change the order (will also change the search results) m.maps = list(reversed(m.maps)) m # Result: ChainMap({'c': 'C', 'b': 'D'}, {'a': 'A', 'b': 'B'}) m["b"] # Result: 'D' # Modify the value (only modify the value in the first mapping found) m["b"] = "w" m # Result: ChainMap({'c': 'C', 'b': 'w'}, {'a': 'A', 'b': 'B'})
The new_child() method creates a new mapping at the front of the maps list with an additional mapping. The new mapping can be passed as a parameter to the new_child() method. Avoid modifying existing underlying data structures.
import collections a = {"a":"A","b":"B"} b = {"c":"C","b":"D"} m = collections.ChainMap(a,b) m # Result: ChainMap({'a': 'A', 'b': 'B'}, {'c': 'C', 'b': 'D'}) mn = m.new_child() mn["b"] = "w" mn # Result: ChainMap({'b': 'w'}, {'a': 'A', 'b': 'B'}, {'c': 'C', 'b': 'D' }) # or c = {"b":"w"} mq = m.new_child(c) mq # Result: ChainMap({'b': 'w'}, {'a': 'A', 'b': 'B'}, {'c': 'C', 'b': 'D' })
2. collections.Counter() [Counter]
Dictionary subclass that counts hashable objects. Use dictionary form to count elements and the number of times they appear in the sequence.
Reference: collections module Counter
3. collections.OrderedDict() [Dictionary remembers the order of addition]
Dictionary subclasses that remember the order of keys added.
# Ordinary dictionary c ={} c[1]="a" c[2]="b" c[3]="c" d = {} d[3]="c" d[2]="b" d[1]="a" c == d # Result: True c # Result: {1: 'a', 2: 'b', 3: 'c'} d # Result: {3: 'c', 2: 'b', 1: 'a'} #OrderedDict import collections a = collections.OrderedDict() a[1]="a" a[2]="b" a[3]="c" b = collections.OrderedDict() b[3]="c" b[2]="b" b[1]="a" a==b # Result: False a # Result: OrderedDict([(1, 'a'), (2, 'b'), (3, 'c')]) b # Result: OrderedDict([(3, 'c'), (2, 'b'), (1, 'a')])
Use the move_to_end() method to move elements to the end (last=True) or beginning (last=False) position.
import collections a = collections.OrderedDict() a[1]="a" a[2]="b" a[3]="c" a # Result: OrderedDict([(1, 'a'), (2, 'b'), (3, 'c')]) # Move key 2 to the end position a.move_to_end(2) a # Result: OrderedDict([(1, 'a'), (3, 'c'), (2, 'b')]) # Move key 3 to the starting position a.move_to_end(3,last=False) a # Result: OrderedDict([(3, 'c'), (1, 'a'), (2, 'b')])
4. collections.defaultdict() [Missing keys call the factory function to return the default value]
Dictionary subclasses that call factory functions to provide missing values.
Factory functions set default values in advance. Use the factory function as a parameter to defaultdict. If there is no key, the factory function is called to return the default value.
import collections def default_factory(): return "default value" a = collections.defaultdict(default_factory) a["a"] = 9 a # Result: defaultdict(<function default_factory at 0x00000278C2482520>, {'a': 9}) a["a"] # Result: 9 a["b"] # 'default value' a # Result: defaultdict(<function default_factory at 0x00000278C2482520>, {'a': 9, 'b': 'default value'})
import collections m = collections.defaultdict(int) m["a"] = 9 m # Result: defaultdict(<class 'int'>, {'a': 9}) m["a"] # Result: 9 m["b"] # 0 m # Result: defaultdict(<class 'int'>, {'a': 9, 'b': 0}) n = collections.defaultdict(list) n["a"].append(9) n # Result: defaultdict(<class 'list'>, {'a': [9]}) n["a"] # Result: [9] n["b"] # [] n # Result: defaultdict(<class 'list'>, {'a': [9], 'b': []})
5. collections.deque() [double-ended queue]
Both ends can be added and removed.
Reference: collections module deque
6. collections.namedtuple() [named tuple]
Create a tuple subclass with named fields. collections.namedtuple(tuple subclass name, [named field 1, named field 2,…])
Ordinary tuples: Use index to access elements in the tuple. Named tuples: Access elements using named fields.
The class created by the named tuple does not use an instance dictionary and can use memory more efficiently; however, attribute access is not as efficient as a class, and the number of fields is inconvenient to increase.
All operations on ordinary tuples still work on named tuples.
import collections Mytuple = collections.namedtuple('Mytuple',['name','age']) people1 = Mytuple('Jack',18) people1.name # Result: 'Jack' people1.age # Result: 18 people1 # Result: Mytuple(name='Jack', age=18) people2 = Mytuple(name='Tom',age=33) people2.name # Result: 'Tom' people2.age # Result: 33 people2 # Result: Mytuple(name='Tom', age=33) # Equivalent to class Mytuple(object): def __init__(self,name,age): self.name = name self.age = age people1 = Mytuple('Jack',18) people1.name # Result: 'Jack' people1.age # Result: 18 people2 = Mytuple('Tom',33) people2.name # Result: 'Tom' people2.age # Result: 33
Neither named tuples nor ordinary tuples can be modified. But named tuples can use the _replace() method to create new instances and replace the value of a field.
import collections Mytuple = collections.namedtuple('Mytuple',['name','age']) people1 = Mytuple('Jack',18) people1.name # Result: 'Jack' people1.age # Result: 18 people1 # Result: Mytuple(name='Jack', age=18) people2 = people1._replace(age=20) people2.name # Result: 'Jack' people2.age # Result: 20 people2 # Result: Mytuple(name='Jack', age=20)
Use the _asdict() method to convert a namedtuple instance into an OrderedDict instance. And the keys of OrderedDict and namedtuple fields are in the same order.
import collections Mytuple = collections.namedtuple('Mytuple',['name','age']) people1 = Mytuple('Jack',18) people1 # Result: Mytuple(name='Jack', age=18) people1._asdict() # Result: {'name': 'Jack', 'age': 18}
7. collections.abc()
Abstract base class for containers. APIs are defined for Python’s built-in container data structures and container data structures defined by the collections module.
import collections [x for x in dir(collections.abc) if not x.startswith('_')] # result: ['AsyncGenerator', 'AsyncIterable', 'AsyncIterator', 'Awaitable', 'ByteString', 'Callable', 'Collection', 'Container', 'Coroutine', 'Generator', 'Hashable', 'ItemsView', 'Iterable', 'Iterator', 'KeysView', 'Mapping', 'MappingView', 'MutableMapping', 'MutableSequence', 'MutableSet', 'Reversible', 'Sequence', 'Set', 'Sized', 'ValuesView']
8. collections.UserDict()
A wrapper around dictionary objects to facilitate dictionary subclassing.
9. collections.UserList()
A wrapper around list objects to facilitate list subclassing.
10. collections.UserString()
A wrapper around string objects to facilitate string subclassing.
Supplement: collections – Container datatypes – Python 3.12.0 documentation