dict.setdefault returns the existing value for a key or inserts and returns the supplied default when the key is absent.
Python dict.setdefault: the returned collection remains mutable shared state
Operation contract
The shipment index groups receipt IDs by route. The first call installs a new list; a later call returns that same list and appends to it. The identifier is then added through a separate alias, proving that the dictionary retained mutable state rather than a copy. This is useful inside one owned aggregation pass, but it is an implicit mutation boundary.
Failure and ownership boundary
The default expression is evaluated before setdefault is called, even when the key already exists. Do not use a side-effecting or expensive factory there; defaultdict can defer construction. Neither form provides thread-safe compound updates. Python defaultdict: missing-key reads can create state, Python dictionary views: iteration sees a live mapping, not a snapshot and Python shallow and deep copies: preserve aliases deliberately make the alternatives explicit.
Working program
by_route = {}
route_receipts = by_route.setdefault("north", [])
route_receipts.append("R41")
same_list = by_route.setdefault("north", [])
same_list.append("R42")
print(by_route)
print(route_receipts is same_list)
print(route_receipts is by_route["north"])Output
{'north': ['R41', 'R42']}
True
TrueCosts and limits
Average mapping lookup and insertion are constant time under ordinary hash behavior, while each append is amortized constant time. The lists retain every grouped receipt; no bound follows from setdefault itself.
Common Mistakes
- The returned list is an alias, not a snapshot.
- A default expression still runs when the key is already present.
Connected lessons
Python defaultdict: missing-key reads can create state, Python dictionary views: iteration sees a live mapping, not a snapshot, Python shallow and deep copies: preserve aliases deliberately.
