collections.defaultdict
Overview
`collections.defaultdict(factory)` is a dict that auto-creates a value the first time you touch a missing key, using the zero-argument `factory` you pass. It removes the 'check if key exists, else initialize' boilerplate. from collections import defaultdict groups = defaultdict(list) # missing key -> [] groups['a'].append(1) # no KeyError; makes [] then appends counts = defaultdict(int) # missing key -> 0 counts['x'] += 1 # 0 + 1 The factory is any zero-arg callable: `list`→`[]`, `int`→`0`, `set`→`set()`, `dict`→`{}`, or your own `lambda: ...`. Key subtlety: merely *accessing* a missing key (`d[k]`) inserts the default and grows the dict — a side effect a plain dict doesn't have.
Grouping and counting are everywhere — bucketing records by a field, tallying frequencies, building adjacency lists for graphs. `defaultdict` makes these one-liners and shows up constantly in interview solutions.
Where used: Grouping records by a key, Frequency counting / tallies, Graph adjacency lists
Why learn this
- Grouping and tallying are among the most common data-shaping tasks, and defaultdict turns them into clean one-liners.
- Graph problems (adjacency lists) and interview questions lean on it heavily.
Code walkthrough
from collections import defaultdict
counts = defaultdict(int)
for ch in 'mississippi':
counts[ch] += 1
print(dict(counts))
Focus: counts[ch] += 1 (missing key starts at 0, so += works with no setup)
Common mistakes
- Passing the factory's result instead of the factory: `defaultdict(list)` is correct — pass the callable. `defaultdict(list())` passes an already-made empty list (not callable), which raises TypeError. The factory must be called per missing key, so you pass `list`, not `list()`.
- Accidentally creating keys by reading them: With a defaultdict, `if d[k]:` inserts `k` with its default as a side effect even when you only meant to check. Use `k in d` or `d.get(k)` to test membership without mutating.
- Wrong factory for the job: Use `int` for counters (0), `list` for appending, `set` for unique membership. Using `list` when you meant `int` (or vice-versa) leads to `+=` on a list or `.append` on an int errors.
Glossary
- factory function
- A zero-argument callable that produces the default value for a missing key. Example: `defaultdict(list)` calls `list()` to make `[]`.
Recall questions
- What does the argument to `defaultdict` have to be, and what does it do?
- Why is `defaultdict(list)` correct but `defaultdict(list())` an error?
- How can reading a key from a defaultdict change the dictionary?
Understanding checks
What are the two printed lines?
[] then 1
Accessing missing key 'x' triggers the `list` factory, so it prints `[]` — and that access also inserts 'x' into the dict, so its length is now 1 (the read had a side effect).
Why does this raise an error?
`int()` is the value `0`, not a callable; defaultdict needs a factory function, so pass `int` (without parentheses).
defaultdict calls the factory for each missing key. `int` is callable and returns 0; `int()` is already 0 and can't be called, causing a TypeError on the first missing-key access.
Practice tasks
Group words by first letter
Given the list of words, build a dict mapping each first letter to the list of words starting with it, using defaultdict so you never check for missing keys.
Continue learning
Previous: Dictionaries: operations and use cases
Next: collections.Counter