Common Dictionary Operations

Beyond get/set/delete, real programs perform a handful of dictionary operations over and over: merging configurations, inverting a mapping, counting, grouping, and picking the max or min by value. Each of these has a short, idiomatic Python solution that avoids explicit loops and is easier to read and to maintain.

Merging two dictionaries combines configuration or user data. a | b (Python 3.9+) returns a new dict where b's keys override a's; a.update(b) does the same in place. For multi-level merges, loop through b.items() manually or reach for a helper library.

Inverting a dict (swapping keys and values) is a one-line dict comprehension: {v: k for k, v in d.items()}. It only makes sense when values are unique and hashable; duplicates silently become a single entry. Grouping by a derived key, on the other hand, is where defaultdict(list) and setdefault shine.

Finally, summarizing a dictionary — pick the key with the largest value, sort by value, total all the counts — relies on max(d, key=d.get), sorted(d.items(), key=lambda p: p[1]), and sum(d.values()). These one-liners replace many lines of manual tracking and are nearly always the right way.

Merging and inverting

a | b is the cleanest way to merge. If you need to combine values instead of overwriting (sum them, concatenate lists), loop explicitly: result.setdefault(k, 0) + v. dict.fromkeys(keys, default) is a convenient way to build a dict with many keys pointing at the same default value.

When inverting, guard against duplicates by inverting into a defaultdict(list): each value becomes a bucket holding every original key mapped to it.

Top-k and sort-by-value

max(d, key=d.get) finds the key with the largest value. For top-k, use sorted(d.items(), key=lambda p: p[1], reverse=True)[:k] or collections.Counter(...).most_common(k). Both run in O(n log n); the Counter approach is the most self-documenting when you are already counting.

To sort an existing dict by value without losing keys, remember that the result is a list of tuples. Wrap it in dict(...) if you want an ordered dict back (insertion order is preserved in all modern Python versions).

The idiomatic dictionary-algebra tools.

ToolPurpose
a | b
operator (3.9+)
Returns a merged copy of two dicts.
a |= b
operator
Merges b into a in place.
dict.fromkeys(keys, v)
classmethod
Builds a dict with the same value for many keys.
max(d, key=d.get)
built-in
Returns the key with the largest value.
Counter.most_common(k)
method
Returns the k most common items and their counts.
sum(d.values())
built-in
Totals the numeric values of a dict.
defaultdict(list)
factory
Auto-creates an empty list for new keys.
operator.itemgetter(1)
factory
Returns a callable that extracts position 1.

Common Dictionary Operations code example

The script below runs a small population-by-city analysis touching every operation listed above.

# Lesson: Common Dictionary Operations
from collections import Counter, defaultdict
from operator import itemgetter

population = {"oslo": 700_000, "rome": 2_800_000, "lima": 9_600_000}
updates    = {"oslo": 720_000, "tokyo": 13_960_000}

merged = population | updates
print("merged:", merged)

total = sum(merged.values())
biggest = max(merged, key=merged.get)
top2 = sorted(merged.items(), key=itemgetter(1), reverse=True)[:2]
print("total:  ", total)
print("biggest:", biggest)
print("top 2:  ", top2)

inverted = {v: k for k, v in merged.items()}
print("inverted (unique values):", inverted)

# Grouping by country
rows = [("oslo", "NO"), ("rome", "IT"), ("milan", "IT"), ("lima", "PE")]
by_country: defaultdict[str, list[str]] = defaultdict(list)
for city, country in rows:
    by_country[country].append(city)
print("grouped:", dict(by_country))

# Counter as a specialized dict
words = "one two two three three three".split()
counts = Counter(words)
print("counts: ", counts.most_common())

What to look for in the script:

1) `|` creates a merged copy; the original dicts are untouched.
2) `max(d, key=d.get)` leverages the fact that `d.get(k)` returns the value for key k.
3) Inverting a dict silently drops duplicates; consider defaultdict(list) when values collide.
4) `Counter(iterable).most_common()` is the shortest way to build a frequency table.

Practice combining values and sorting by value.

# Example A: sum overlapping values instead of overwriting
a = {"x": 1, "y": 2}
b = {"y": 3, "z": 4}
combined: dict[str, int] = {}
for k, v in list(a.items()) + list(b.items()):
    combined[k] = combined.get(k, 0) + v
print(combined)   # {'x': 1, 'y': 5, 'z': 4}

# Example B: sort by value without losing the keys
scores = {"ana": 90, "ben": 72, "cai": 85}
ordered = dict(sorted(scores.items(), key=lambda p: p[1], reverse=True))
print(ordered)

Small invariants to confirm the behaviors.

assert ({"a": 1} | {"a": 2}) == {"a": 2}
assert dict.fromkeys("abc", 0) == {"a": 0, "b": 0, "c": 0}
assert sum({"a": 1, "b": 2}.values()) == 3
assert max({"a": 5, "b": 3}, key={"a": 5, "b": 3}.get) == "a"

Running prints:

merged: {'oslo': 720000, 'rome': 2800000, 'lima': 9600000, 'tokyo': 13960000}
total:   27080000
biggest: tokyo
top 2:   [('tokyo', 13960000), ('lima', 9600000)]
inverted (unique values): {720000: 'oslo', 2800000: 'rome', 9600000: 'lima', 13960000: 'tokyo'}
grouped: {'NO': ['oslo'], 'IT': ['rome', 'milan'], 'PE': ['lima']}
counts:  [('three', 3), ('two', 2), ('one', 1)]