Why doesn't a python dict.update return the object?
Master System Design with Codemia
Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.
Introduction
dict.update() mutates a dictionary in place and returns None, which feels surprising if you expect fluent method chaining. In Python, though, that behavior is deliberate and consistent with the design of many mutable container methods. The language uses the return value to signal whether a method is meant for side effects or meant to produce a new object.
Python Uses a Convention for Mutable Containers
Several built-in mutable types follow the same pattern as dict.update().
- '
list.sort()sorts in place and returnsNone' - '
list.reverse()reverses in place and returnsNone' - '
set.update()mutates in place and returnsNone'
That convention makes side effects visible. When you see one of these methods, the message is “this object changes here.”
The output shows the intent clearly: the list changed, and there is no separate result object to capture.
What dict.update() Actually Does
update() takes key-value pairs from another mapping or iterable and writes them into the existing dictionary.
Two important things happen:
- existing keys are overwritten by incoming values
- new keys are added to the same dictionary object
That means the identity of base does not change. Only its contents change.
Why Returning the Dictionary Would Be Misleading
If update() returned the same dictionary, many people would start chaining mutation-heavy expressions and treating side-effecting code as though it were purely functional. Python generally discourages that style for built-in mutable containers.
The design goal is clarity. A statement such as config.update(env_overrides) reads like a mutation. An expression such as config = config.update(env_overrides) would suggest a new value is being built, even though the original object is being modified.
That distinction matters in debugging, code review, and reasoning about aliasing. If two variables reference the same dictionary, in-place mutation affects both views of that object.
The Common Mistake
The classic bug is capturing the return value.
merged is None, because the real result is that a was changed.
The correct version depends on your goal.
If you want mutation:
If you want a new dictionary instead:
And in modern Python:
That last form is often the cleanest non-mutating merge.
API Design Lesson: Mutation and Pure Results Should Be Separate
This convention is useful when designing your own classes as well. A method that mutates state should generally make that obvious. A method that returns a transformed value should usually not mutate the original object.
The names tell the story: one method mutates, the other returns a modified copy.
Choose the Right Merge Style for the Use Case
There is no single best merge style. In-place updates are good when you deliberately maintain mutable state, such as loading configuration in stages. New-object merges are better when you want predictable immutable-style flow.
That style keeps the original dictionaries unchanged and makes precedence order explicit.
Common Pitfalls
- Assigning the return value of
dict.update()and expecting a merged dictionary. - Forgetting that
update()mutates the original object and therefore affects every reference to it. - Mixing in-place and immutable merge styles inconsistently within the same code path.
- Using
update()in a fluent chain even though the built-in API is designed to signal side effects withNone. - Failing to document precedence when multiple dictionaries are merged in sequence.
Summary
- '
dict.update()returnsNonebecause it mutates a dictionary in place.' - That behavior matches a broader Python convention for mutable container methods.
- The design helps distinguish side-effecting operations from value-producing ones.
- Use
update()when mutation is intended, and use merge expressions when you need a new dictionary. - Clear separation between mutation and transformation makes Python code easier to reason about.

