~22 min · collections, deque, counter, defaultdict, namedtuple
Level 0Curious
0 XP0/93 lessons0/23 achievements
0/100 XP to next level100 XP to go0% complete
The Pythonist's first stop in the standard library
If list and dict covered everything, you'd never need collections. They don't. The module gives you specialized data structures for problems where the basic types are awkward: queues that need to pop from the front, counters of how often things appear, dicts that auto-fill on first access, and tuples with named fields.
deque — the double-ended queue
A list is fast at appending/popping the right end (O(1)) and slow on the left (O(n)). deque is O(1) on both ends. Use it for queues (FIFO), sliding windows, breadth-first traversals — anything that needs left-side operations to be cheap. deque(maxlen=N) gives you a bounded ring buffer that auto-discards from the other end when full.
Counter — counting things made easy
Counter(iterable) counts occurrences. The result is a dict subclass with .most_common(n), addition / subtraction across counters, and missing-keys-return-zero behavior. Replaces hand-written count loops cleanly.
defaultdict — auto-fill on first access
defaultdict(list) creates a dict that, on d[missing_key], calls the factory and inserts the result before returning it. Perfect for grouping: groups[key].append(item) just works, no setdefault dance. Pass any zero-arg callable as the factory.
namedtuple — and why dataclass might be better
We saw namedtuple in the data track. It's still useful for cheap, immutable, tuple-shaped records. For richer needs (defaults, methods, type annotations), use dataclass instead. The choice is shape: pure tuple = namedtuple; record with behavior = dataclass.
Principle: Reach for collections when the basic types are starting to feel awkward. Every named structure here represents a pattern Python's authors have refined. You don't have to discover that you need a deque the hard way.
Code
deque — fast on both ends·python
from collections import deque
q = deque([1, 2, 3])
q.append(4) # right
q.appendleft(0) # left
print(q) # deque([0, 1, 2, 3, 4])
q.pop() # right
q.popleft() # left
print(q) # deque([1, 2, 3])
# Bounded ring buffer
recent = deque(maxlen=3)
for x in [1, 2, 3, 4, 5]:
recent.append(x)
print(recent) # deque([3, 4, 5], maxlen=3)
Counter — counting made trivial·python
from collections import Counter
text = "the quick brown fox jumps over the lazy dog the"
words = text.split()
c = Counter(words)
print(c) # Counter({'the': 3, ...})
print(c.most_common(3)) # [('the', 3), ('quick', 1), ('brown', 1)]
# Counters support arithmetic
a = Counter("hello")
b = Counter("world")
print(a + b) # Counter({'l': 3, 'o': 2, ...})
print(a - b) # only positive — characters in a but not b
# Missing keys return 0, not KeyError
print(c["nonexistent"]) # 0
defaultdict — auto-fill on first access·python
from collections import defaultdict
# Group items by first letter
words = ["apple", "banana", "avocado", "blueberry", "cherry"]
groups = defaultdict(list)
for w in words:
groups[w[0]].append(w) # works because of defaultdict
print(dict(groups))
# {'a': ['apple', 'avocado'], 'b': ['banana', 'blueberry'], 'c': ['cherry']}
# Counter use case
counts = defaultdict(int)
for c in "hello world":
counts[c] += 1 # int() = 0 — auto-init to zero
print(dict(counts))
ChainMap and OrderedDict — the lesser-used two·python
from collections import ChainMap, OrderedDict
# ChainMap — multiple dicts as one (lookup-only)
defaults = {"theme": "dark", "font": "mono"}
user = {"theme": "light"}
combined = ChainMap(user, defaults)
print(combined["theme"]) # 'light' — user wins
print(combined["font"]) # 'mono' — falls through to defaults
# OrderedDict — was useful pre-3.7. Now plain dict has insertion order.
# Still has .move_to_end() for explicit reordering.
od = OrderedDict([("a", 1), ("b", 2), ("c", 3)])
od.move_to_end("a")
print(list(od)) # ['b', 'c', 'a']
Given a list of words: words = "the quick brown fox jumps over the lazy dog the quick fox".split(): (a) Use Counter to find the 3 most common words. (b) Use defaultdict(list) to group words by their first letter. (c) Use deque(maxlen=5) to keep only the last 5 words seen as you iterate the list. Print all three results.
Progress
Progress is local-only — sign in to sync across devices.