Dictionary Methods & Comprehensions

Beyond basic lookups, dictionaries have methods for providing defaults, updating in bulk and building from other data. Dictionary comprehensions let you transform and filter a whole dictionary in one expression.

get and setdefault

PY defaults.py
config = {"host": "localhost"}

print(config.get("port", 8080))
print(config)

port = config.setdefault("port", 8080)
print(port, config)

config.setdefault("port", 9999)
print(config["port"])
Output
8080
{'host': 'localhost'}
8080 {'host': 'localhost', 'port': 8080}
8080

get only reads; setdefault reads the value if the key exists, and otherwise inserts the default and returns it. It's handy for grouping:

PY grouping.py
words = ["apple", "avocado", "banana", "blueberry", "cherry"]

by_letter = {}
for w in words:
    by_letter.setdefault(w[0], []).append(w)

print(by_letter)
Output
{'a': ['apple', 'avocado'], 'b': ['banana', 'blueberry'], 'c': ['cherry']}

update

PY update.py
profile = {"name": "Ana", "city": "Lisbon"}

profile.update({"city": "Porto", "job": "engineer"})
profile.update(age=31)
print(profile)
Output
{'name': 'Ana', 'city': 'Porto', 'job': 'engineer', 'age': 31}

Removing items

PY remove.py
d = {"a": 1, "b": 2, "c": 3}

print(d.pop("a"))
print(d.popitem())
print(d)
d.clear()
print(d)
Output
1
('c', 3)
{'b': 2}
{}

popitem removes and returns the most recently inserted pair — useful for processing a dictionary like a stack.

fromkeys and copy

PY fromkeys.py
fields = ["name", "email", "phone"]
blank_form = dict.fromkeys(fields, "")
print(blank_form)

copy = blank_form.copy()
copy["name"] = "Ana"
print(blank_form["name"] == "", copy["name"])
Output
{'name': '', 'email': '', 'phone': ''}
True Ana
Trap: dict.fromkeys(keys, []) gives every key the same list object, so appending to one appends to all. Use a comprehension instead: {k: [] for k in keys}.

Dictionary comprehensions

PY comprehensions.py
prices = {"tea": 3.0, "cake": 4.5, "juice": 5.0, "water": 1.0}

with_tax = {item: round(p * 1.2, 2) for item, p in prices.items()}
print(with_tax)

expensive = {item: p for item, p in prices.items() if p >= 4}
print(expensive)

inverted = {p: item for item, p in prices.items()}
print(inverted[4.5])

squares = {n: n * n for n in range(1, 6)}
print(squares)
Output
{'tea': 3.6, 'cake': 5.4, 'juice': 6.0, 'water': 1.2}
{'cake': 4.5, 'juice': 5.0}
cake
{1: 1, 2: 4, 3: 9, 4: 16, 5: 25}

Building dictionaries from two lists

PY zip.py
names = ["Ana", "Ben", "Cleo"]
scores = [91, 78, 85]

results = dict(zip(names, scores))
print(results)

ranked = {name: rank for rank, name in enumerate(sorted(results, key=results.get, reverse=True), 1)}
print(ranked)
Output
{'Ana': 91, 'Ben': 78, 'Cleo': 85}
{'Ana': 1, 'Cleo': 2, 'Ben': 3}

Sorting a dictionary

Dictionaries keep insertion order, so "sorting" one means building a new one from sorted items:

PY sort.py
population = {"Porto": 232_000, "Lisbon": 545_000, "Braga": 193_000}

by_name = dict(sorted(population.items()))
by_size = dict(sorted(population.items(), key=lambda kv: kv[1], reverse=True))

print(list(by_name))
print(list(by_size))
Output
['Braga', 'Lisbon', 'Porto']
['Lisbon', 'Porto', 'Braga']

Safely reading nested data

PY nested_get.py
response = {"user": {"profile": {"city": "Oslo"}}}
empty = {"user": {}}

def city_of(data):
    return data.get("user", {}).get("profile", {}).get("city", "unknown")

print(city_of(response), city_of(empty), city_of({}))
Output
Oslo unknown unknown

Quick reference

MethodDoes
get(k, default)Read with a fallback
setdefault(k, default)Read, or insert the default
update(other), |=Merge in place
pop(k, default), popitem(), clear()Remove
keys(), values(), items()Views for looping
dict.fromkeys(keys, value), copy()Create

Try it yourself

Try it yourself
Console output