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.
| Tool | Purpose |
|---|---|
a | boperator (3.9+) | Returns a merged copy of two dicts. |
a |= boperator | 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)]