Skip to content
AITroveRead. Build. Understand.
Make this comfortable

Python dict.setdefault: the returned collection remains mutable shared state

Last updated: 30 Sept 20264 min read
tutorial
IntermediateBy AITrove Editorial

dict.setdefault returns the existing value for a key or inserts and returns the supplied default when the key is absent.

Download Python source kit

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

python
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

Output
{'north': ['R41', 'R42']}
True
True

Costs 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.

python
setdefault-aliasing
Storage details