Python Story

Chapter #10 – Collections Library

collections, itertools, functools

10.0 Prologue

Three standard library modules — collections, itertools, and functools — extend Python's built-in data structures and functional programming tools. Knowing them avoids reinventing common patterns.

10.1 Counter

Counter is a dict subclass that counts hashable objects. It supports arithmetic operations on counts: from collections import Counter text = "abracadabra" c = Counter(text) print(c) # Counter({'a': 5, 'b': 2, 'r': 2, 'c': 1, 'd': 1}) print(c.most_common(3)) # [('a', 5), ('b', 2), ('r', 2)] words = "the cat sat on the mat".split() wc = Counter(words) print(wc["the"]) # 2 wc.update(["the", "cat"]) # add more counts

10.2 defaultdict

defaultdict calls a factory function to create default values for missing keys, eliminating explicit KeyError handling: from collections import defaultdict # group words by first letter words = ["apple", "apricot", "banana", "avocado", "blueberry"] by_letter = defaultdict(list) for w in words: by_letter[w[0]].append(w) # {'a': ['apple', 'apricot', 'avocado'], 'b': ['banana', 'blueberry']} # count without Counter freq = defaultdict(int) for w in words: freq[w] += 1

10.3 deque

deque (double-ended queue) provides O(1) append and pop from both ends, unlike a list where left-end operations are O(n): from collections import deque q = deque([1, 2, 3]) q.appendleft(0) # [0, 1, 2, 3] q.append(4) # [0, 1, 2, 3, 4] q.popleft() # 0 — O(1) q.rotate(1) # [4, 1, 2, 3] — rotate right by 1 # bounded buffer: automatically discards oldest when full recent = deque(maxlen=5) for i in range(10): recent.append(i) print(list(recent)) # [5, 6, 7, 8, 9]

10.4 namedtuple and OrderedDict

namedtuple creates lightweight immutable classes with named fields. typing.NamedTuple is the typed equivalent: from collections import namedtuple from typing import NamedTuple Point = namedtuple("Point", ["x", "y"]) p = Point(3, 4) print(p.x, p.y) # 3 4 print(p._asdict()) # {'x': 3, 'y': 4} class Color(NamedTuple): r: int g: int b: int alpha: float = 1.0 red = Color(255, 0, 0) OrderedDict was the insertion-order-preserving dict before Python 3.7. Today regular dict preserves order; OrderedDict is mainly useful for its move_to_end() method and for LRU-cache implementations.

10.5 itertools

itertools provides composable building blocks for lazy iteration: import itertools # infinite iterators counter = itertools.count(start=1, step=2) # 1, 3, 5, ... cycle = itertools.cycle("ABC") # A B C A B C ... repeated = itertools.repeat(42, times=3) # 42 42 42 # slicing infinite iterators first10 = list(itertools.islice(counter, 10)) # combinatorics perms = list(itertools.permutations("ABC", 2)) # 6 pairs combs = list(itertools.combinations("ABCD", 2)) # 6 pairs # chaining and grouping chained = list(itertools.chain([1, 2], [3, 4], [5])) # [1,2,3,4,5] data = sorted([("a", 1), ("b", 2), ("a", 3)], key=lambda t: t[0]) for key, group in itertools.groupby(data, key=lambda t: t[0]): print(key, list(group))

10.6 functools

functools provides higher-order functions for functional-style programming: import functools, operator # reduce — fold a sequence total = functools.reduce(operator.add, [1, 2, 3, 4, 5]) # 15 # partial — fix some arguments double = functools.partial(operator.mul, 2) print(double(7)) # 14 # lru_cache — memoization @functools.lru_cache(maxsize=None) def fib(n: int) -> int: return n if n < 2 else fib(n - 1) + fib(n - 2) print(fib(50)) # fast, O(n) due to caching print(fib.cache_info()) # cached_property — compute once, store as attribute class Circle: def __init__(self, r: float) -> None: self.r = r @functools.cached_property def area(self) -> float: import math return math.pi * self.r ** 2 @functools.wraps(f) preserves the wrapped function's name, docstring, and annotations — always use it inside decorator wrappers.

10.7 Epilogue

This chapter covered the collections, itertools, and functools modules — workhorses that replace verbose manual patterns with concise, well-tested utilities. The final chapter explores Python's most interesting advanced features.

10.8 References

collections module — python.org
itertools module — python.org
functools module — python.org
itertools — Real Python