You have two dicts — {"host": "localhost", "port": 5432} and {"port": 8080, "user": "admin"} — and you want one merged config where the second dict's values win on conflicts: {"host": "localhost", "port": 8080, "user": "admin"}. How do you combine them?
I'd copy the first dict, then loop over the second and assign each key. Three or four lines?
Python has a one-expression shortcut — the dict-spread syntax. {**a, **b} creates a new dict by unpacking both inputs, with later keys overriding earlier ones:
defaults = {"host": "localhost", "port": 5432}
overrides = {"port": 8080, "user": "admin"}
merged = {**defaults, **overrides}
# {"host": "localhost", "port": 8080, "user": "admin"}The ** unpacks each dict's key-value pairs into the outer braces. The second ** happens after the first, so its keys overwrite.
So **a expands to the key-value pairs of a inside the new dict literal? That's the same ** used for keyword arguments in function calls?
Exactly. It's the unpacking operator repurposed. In a function call, f(**config) spreads config as keyword args. In a dict literal, {**a, **b} spreads them as entries. Same operator, same idea:
def merge_dicts(a: dict, b: dict) -> dict:
return {**a, **b}One expression, no mutation of the inputs. Both a and b are untouched.
And if both dicts are empty?
{**{}, **{}} is {}. Same graceful behavior as comprehensions. If one is empty and the other has entries, the non-empty one passes through unchanged — union with empty is identity.
This is perfect for config merging — defaults plus user overrides, base settings plus environment-specific tweaks. The spread makes it declarative.
That's the idiomatic pattern in modern Python. Before {**a, **b} existed, people used dict(a, **b) or two-step copies. The spread is clearer and scales to three or four dicts just by adding more ** entries.
TL;DR: {**a, **b} merges two dicts; later keys win on conflicts.
** overrides earlier on shared keys{**a, **b, **c, **d} scales directly| Input | Merged |
|---|---|
{"x": 1}, {"x": 2} | {"x": 2} — right wins |
{"x": 1}, {"y": 2} | {"x": 1, "y": 2} — no conflict |
{}, {"y": 2} | {"y": 2} — left empty |
The ** operator unpacks dict entries in place — the same mechanism used for keyword-argument spread in function calls.
You have two dicts — {"host": "localhost", "port": 5432} and {"port": 8080, "user": "admin"} — and you want one merged config where the second dict's values win on conflicts: {"host": "localhost", "port": 8080, "user": "admin"}. How do you combine them?
I'd copy the first dict, then loop over the second and assign each key. Three or four lines?
Python has a one-expression shortcut — the dict-spread syntax. {**a, **b} creates a new dict by unpacking both inputs, with later keys overriding earlier ones:
defaults = {"host": "localhost", "port": 5432}
overrides = {"port": 8080, "user": "admin"}
merged = {**defaults, **overrides}
# {"host": "localhost", "port": 8080, "user": "admin"}The ** unpacks each dict's key-value pairs into the outer braces. The second ** happens after the first, so its keys overwrite.
So **a expands to the key-value pairs of a inside the new dict literal? That's the same ** used for keyword arguments in function calls?
Exactly. It's the unpacking operator repurposed. In a function call, f(**config) spreads config as keyword args. In a dict literal, {**a, **b} spreads them as entries. Same operator, same idea:
def merge_dicts(a: dict, b: dict) -> dict:
return {**a, **b}One expression, no mutation of the inputs. Both a and b are untouched.
And if both dicts are empty?
{**{}, **{}} is {}. Same graceful behavior as comprehensions. If one is empty and the other has entries, the non-empty one passes through unchanged — union with empty is identity.
This is perfect for config merging — defaults plus user overrides, base settings plus environment-specific tweaks. The spread makes it declarative.
That's the idiomatic pattern in modern Python. Before {**a, **b} existed, people used dict(a, **b) or two-step copies. The spread is clearer and scales to three or four dicts just by adding more ** entries.
TL;DR: {**a, **b} merges two dicts; later keys win on conflicts.
** overrides earlier on shared keys{**a, **b, **c, **d} scales directly| Input | Merged |
|---|---|
{"x": 1}, {"x": 2} | {"x": 2} — right wins |
{"x": 1}, {"y": 2} | {"x": 1, "y": 2} — no conflict |
{}, {"y": 2} | {"y": 2} — left empty |
The ** operator unpacks dict entries in place — the same mechanism used for keyword-argument spread in function calls.
Write `merge_dicts(a, b)` that returns a new dict containing every key from both `a` and `b`. When a key exists in both, `b`'s value should win. Use the `{**a, **b}` spread syntax.
Tap each step for scaffolded hints.
No blank-editor panic.