Defaultdict calls its default factory for a missing subscript lookup and stores the resulting value under that key.
Python defaultdict: missing-key reads can create state
Operation contract
The batch groups accepted receipt IDs by region using a list factory. Calling get for an unknown region does not invoke the factory, while indexing that region creates an empty group. The fixture makes both behaviors visible because a supposedly read-only inspection can otherwise change exported group keys.
Failure and ownership boundary
The factory must produce independent mutable containers. Reusing one shared list would couple unrelated groups. This helper assumes records have already been validated; grouping is not a schema or authorization check. Python dictionaries: insertion order and duplicate-key replacement and Python aggregation exercise: validate records before returning group totals cover those boundaries.
Working program
from collections import defaultdict
groups = defaultdict(list)
for region, receipt_id in [("DEL", "R-0041"), ("BOM", "R-0042"), ("DEL", "R-0043")]:
groups[region].append(receipt_id)
print(dict(groups))
print(groups.get("BLR"))
print("BLR" in groups)
print(groups["BLR"])
print("BLR" in groups)Output
{'DEL': ['R-0041', 'R-0043'], 'BOM': ['R-0042']}
None
False
[]
TrueCosts and limits
Grouping n accepted records takes expected O(n) mapping operations and O(n+g) references for g groups. A missing-key factory can perform arbitrary work; the list factory here creates one empty container.
Common Mistakes
- Get and missing subscript lookup have different mutation behavior.
- Return a fresh mutable value from each factory call.
Connected lessons
Python dictionaries: insertion order and duplicate-key replacement, Python shallow and deep copies: preserve aliases deliberately, Python aggregation exercise: validate records before returning group totals.
Trace the next boundary
Python dict.setdefault: the returned collection remains mutable shared state.
