collections.defaultdict
d[key] on a missing key calls default_factory() with no arguments, stores the result and returns it. Only d[key] does this — get(), "in" and pop() behave exactly like a plain dict.
Common call
groups = defaultdict(list)
Returns
defaultdict(<class 'list'>, {})
Replaces
d.setdefault(k, []).append(v) and "if k not in d" checks
Watch out
pass the TYPE (list), not a call (list())
collections.defaultdict(default_factorydefault_factory — Called with no arguments to make each missing value: list, int, set, dict, a lambda … None behaves like a plain dict (KeyError).type: callable | None · default: None=None, /, [...][...] — Anything dict() accepts: a mapping, key/value pairs, keyword arguments.type: dict arguments · default: null)
→ defaultdict
Demo
Live evaluation
Group words by length with defaultdict(list).
Try:
Inputs
wordslist[str]comma-separated words
Code
from collections import defaultdict groups = defaultdict(list) for w in ['cat', 'horse', 'dog', 'mouse', 'ox']: groups[len(w)].append(w) groups
Result
defaultdict(<class 'list'>, {3: ['cat', 'dog'], 5: ['horse', 'mouse'], 2: ['ox']})
Grouping by len(w) makes the keys ints in first-seen order — 3, 5, 2 for the animals. In the last tab only the key read with square brackets appears in the result: get() returned None and "in" returned False without touching the dict.
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
| default_factory | callable | None | no (None) | Called with no arguments to make each missing value: list, int, set, dict, a lambda … None behaves like a plain dict (KeyError). |
| [...] | dict arguments | no | Anything dict() accepts: a mapping, key/value pairs, keyword arguments. |
Return value
defaultdict — A dict subclass; the remaining arguments are passed to dict().
Attributes
| Attribute | Type | Meaning |
|---|---|---|
| default_factory | callable | None | The factory used by __missing__. Writable: set it to None to stop creating keys. |
Common patterns
Group records
A dict of lists in one line per record.
from collections import defaultdict by_dept = defaultdict(list) for person in people: by_dept[person.dept].append(person.name)
Unique values per key
defaultdict(set) with .add().
from collections import defaultdict tags = defaultdict(set) for post, tag in pairs: tags[post].add(tag)
Nested (two-level) dict
The factory can itself build a defaultdict.
from collections import defaultdict grid = defaultdict(lambda: defaultdict(int)) grid[row][col] += 1
Freeze it when done
Turn it back into a plain dict so later typos raise KeyError.
result = dict(groups)
Examples
1. Missing key gets a fresh list
from collections import defaultdict
d = defaultdict(list)
d['a'].append(1)
d
Returns
defaultdict(<class 'list'>, {'a': [1]})2. int() starts at 0
from collections import defaultdict
d = defaultdict(int)
d['x'] += 5
d['x']
Returns
53. Constant default with a lambda
from collections import defaultdict
d = defaultdict(lambda: 'n/a')
d['missing']
Returns
'n/a'4. Initial contents like dict()
from collections import defaultdict
defaultdict(int, {'a': 1}, b=2)
Returns
defaultdict(<class 'int'>, {'a': 1, 'b': 2})5. default_factory is an attribute
from collections import defaultdict
defaultdict(set).default_factory
Returns
<class 'set'>6. copy() keeps the factory
from collections import defaultdict
d = defaultdict(list, a=[1])
d.copy()
Returns
defaultdict(<class 'list'>, {'a': [1]})7. No factory: plain KeyError
from collections import defaultdict
defaultdict()['k']
Returns
KeyError: 'k'Pitfalls
1. Calling the factory
default_factory must be callable. list() is an empty list, not a factory.
defaultdict(list())
from collections import defaultdict defaultdict(list())
TypeError: first argument must be callable or None
defaultdict(list)
from collections import defaultdict defaultdict(list)
defaultdict(<class 'list'>, {})
2. Lookups that silently add keys
Every d[key] read of a missing key inserts it — even inside an if. Use "in" or get() to look without inserting.
d[key] in a test
from collections import defaultdict d = defaultdict(int) if d['typo'] > 0: pass len(d)
1
d.get(key, 0)
from collections import defaultdict d = defaultdict(int) if d.get('typo', 0) > 0: pass len(d)
0
3. Expecting get() to use the factory
Only __getitem__ calls __missing__. get() returns None (or your default) like any dict.
d.get(key)
from collections import defaultdict print(defaultdict(list).get('k'))
None
d[key]
from collections import defaultdict defaultdict(list)['k']
[]
When to use
Use it
- Building dicts of lists, sets or counters
- Accumulating into keys you do not know in advance
Reach for something else
- Counting → Counter (adds most_common, arithmetic)
- A one-off default at a single call site → dict.get(key, default) or setdefault
- Handing data to code that relies on KeyError → convert with dict(d)
Notes
CPython impl
Modules/_collectionsmodule.c — defaultdict defines __missing__, __repr__, copy/__copy__, __reduce__ and the | operators itself; everything else is inherited from dict
__missing__
dict.__getitem__ calls __missing__(key) for absent keys; defaultdict inserts default_factory() there, or raises KeyError(key) when the factory is None
repr
The factory is shown by its own repr: defaultdict(<class 'list'>, {...}); a lambda factory shows as <function <lambda> at 0x…>
FAQ
A dict subclass from collections that calls a factory (list, int, set …) to create a value for any missing key accessed with d[key], stores it and returns it — so you never get KeyError when building up groups or counts.