Python Collections
Contents
ChainMap
To combine mappings in a manner that preserves values hierarchically, consider using a ChainMap.
The list of mappings is stored internally. Lookups traverse the entire list (in order) until a match is found, while deletions, insertions, and updates only operate on the first mapping.
A simple example would be the Python interpreter's own lookup chain:
import builtins from collections import ChainMap pylookup = ChainMap(locals(), globals(), vars(builtins))
To add a new lowest-priority mapping to an existing ChainMap, update the maps list directly.
from collections import ChainMap inventory = ChainMap(store_inventory, regional_inventory) inventory.maps.append(global_inventory)
To add a new highest-priority mapping to an existing ChainMap, instead create a new object with the new_child() method.
merchandise = inventory.new_child(showroom_inventory)
A ChainMap is much faster than a series of update() calls on a single dictionary, while still offering an ordering of keys that matches such an implementation.
In the context of type annotations, try:
from collections import ChainMap c: ChainMap[str, int] = ChainMap({"table": 1, "chair": 4})
Counter
To aggregate a collection of duplicated values into a collection of pairs of unique values and the number of occurences of that value in the original collection, use a Counter.
from collections import Counter animals_in_residence = Counter(cats=4, dogs=8) # Counter({'cats': 4, 'dogs': 8}) food_orders = Counter(['eggs', 'ham', 'spam']) # Counter({'eggs': 1, 'ham': 1, 'spam': 1}) favorite_colors = Counter() for word in ['red', 'blue', 'red', 'green', 'blue', 'blue']: favorite_colors[word] += 1 # Counter({'blue': 3, 'red': 2, 'green': 1})
In all cases, the insertion order is preserved.
If a lookup fails, a Counter returns 0 rather than raising a KeyError.
To combine Counter objects, try:
from collections import Counter c = Counter(x=2, y=2) c.update(Counter(x=1, y=1)) # Counter({'x': 3, 'y': 3})
On the other hand, to subtract one Counter from another, try:
from collections import Counter c = Counter(x=2, y=2) c.subtract(Counter(x=1, y=1)) # Counter({'x': 1, 'y': 1})
To delete a pair from a Counter, do not set the corresponding value to 0. Instead delete the attribute (del c['key']).
There are also aggregation methods available. totals() returns the sum of all values' counts. most_common(n) returns the n value and count pairs with the highest counts.
In the context of type annotations, try:
from collections import Counter c: Counter[str] = Counter(['eggs', 'ham', 'spam'])
Deque
DefaultDict
NamedTuple
OrderedDict
UserDict
UserList
UserString
Abstract Base Classes
See here for details.