dict.update()
Copy keys and values from another dict (or iterable of pairs, or kwargs) into this dict. Existing keys are silently overwritten.
Common call
config.update(overrides)
Returns
None — the receiving dict grows / changes
Replaces
a for-loop of individual assignments
Watch out
existing keys are OVERWRITTEN, not merged
dict.update([other])
→ None
Demo
Live evaluation
Try:
Inputs
dictdictstarting dict
otherdictpairs to merge
Output
{'a': '1', 'b': '2'}.update({'c': '3', 'd': '4'})
None
The demo shows the DICT STATE after updating. Python actually returns None; the meaningful effect is mutation. When a key exists in both, the value from `other` wins — silently. There is no built-in "fail on collision" mode.
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
| other | dict | iterable[pair] | **kwargs | no (None) | Source of new pairs. Accepts another dict, an iterable of (key, value) pairs, or keyword arguments. Later values win on collision. |
Return value
None — Returns None — the useful effect is mutation. The demo shows the dict state after updating.
Common patterns
Apply user overrides
Start with defaults, layer overrides on top — later wins.
settings = defaults.copy() settings.update(user_overrides)
Merge from an iterable of pairs
update accepts any iterable of 2-tuples, not just dicts.
d.update([("a", 1), ("b", 2)])
Add via keyword arguments
Nice for small, static additions.
d.update(debug=True, retries=3)
Sum counts across dicts
update overwrites — for actual summing, iterate.
for k, v in extra.items(): totals[k] = totals.get(k, 0) + v
Examples
1. Add new pairs
d = {"a": 1}
d.update({"b": 2})
d
Returns
{"a": 1, "b": 2}2. Overwrite existing
d = {"a": 1}
d.update({"a": 99})
d
Returns
{"a": 99}3. From pairs
d = {}
d.update([("a", 1), ("b", 2)])
d
Returns
{"a": 1, "b": 2}4. From kwargs
d = {}
d.update(x=10, y=20)
d
Returns
{"x": 10, "y": 20}5. Returns None
{"a": 1}.update({"b": 2})
Returns
NonePitfalls
1. Silent overwrite of existing keys
No warning, no error — the second value simply replaces the first. Fine when overrides are intended; a bug when you meant to merge or protect existing values.
Data lost
settings = {"port": 8000, "host": "prod.io"} settings.update({"port": 3000, "host": "dev.io"}) settings
{"port": 3000, "host": "dev.io"}
Protect keys
for k, v in overrides.items(): settings.setdefault(k, v) # only adds if absent
existing values preserved
2. Shallow merge — nested dicts get replaced
update copies top-level values as they are. A nested dict is replaced wholesale, not deep-merged. Common footgun in config layering.
Nested wiped
cfg = {"db": {"host": "a", "port": 1}} cfg.update({"db": {"host": "b"}}) cfg
{"db": {"host": "b"}} # port is gone
Deep-merge by hand
cfg["db"].update({"host": "b"}) # or use a recursive merge helper
{"db": {"host": "b", "port": 1}}
3. The `d = d.update(...)` bug
update returns None. Assigning its result back sets your variable to None — the same class of bug as sort and extend.
Now d is None
d = {"a": 1} d = d.update({"b": 2}) print(d)
None
Two options
d.update({"b": 2}) # mutate, keep name # or d = d | {"b": 2} # new dict, replace name (3.9+)
{"a": 1, "b": 2}
4. Iterable of pairs must be 2-length
Passing an iterable whose items are not exactly 2-element (key, value) pairs raises a specific ValueError.
Wrong shape
d.update([("a", 1, 2)])
ValueError: dictionary update sequence element #0 has length 3; 2 is required
Fix the shape
d.update([("a", 1)])
{"a": 1}
When to use
Use it
- Applying overrides or defaults
- Merging config layers where later wins
- Populating a dict from an iterable of pairs
- Small hardcoded additions via kwargs
Reach for something else
- You need to detect collisions → guard with sets first, or iterate manually
- You need a deep merge → recursive helper
- You want a NEW dict without mutating either → `{**a, **b}` or `a | b` (3.9+)
- Summing values across dicts → iterate with dict.get
Notes
Complexity
O(k) where k is the size of the source
Return
None; the dict is mutated in place
CPython impl
Objects/dictobject.c :: dict_update_common
Memory
May reallocate the underlying hash table when it grows past its load factor
Thread-safe
Not safe under concurrent mutation of either dict
FAQ
update mutates the left dict in place and returns None. The `|` operator (Python 3.9+) returns a NEW dict without touching either input. `|=` is the in-place variant, roughly equivalent to update.
History
1.5
update() introduced.
2.4
Accepts an iterable of pairs.
3.9
`|` and `|=` dict merge operators added — the non-mutating and mutating alternatives.