Python Collections


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.


CategoryRicottone