Python Dictionaries

Tutorial 13 of 65 · pythondeck.com Python course

Dictionaries map hashable keys to arbitrary values. Since Python 3.7 they preserve insertion order. Useful methods: get, setdefault, update, pop, items, keys, values. Dict comprehensions and merging with | (3.9+) are idiomatic.

Dictionaries map hashable keys to arbitrary values—Python's primary associative array. They power JSON-like data, caches, frequency tables, and object namespaces. Config files, HTTP headers, and query parameters all map naturally to string keys and scalar or nested values.

Insertion-ordered dicts (3.7+) make them suitable for serializing config while preserving readability; still treat them as mappings, not sequences. JSON APIs and REST payloads map naturally to dicts nested with lists and scalars.

Literals: {"a": 1}; constructors: dict(), dict.fromkeys.

Access: d[key] raises KeyError; d.get(key, default) is safe.

Views: .keys(), .values(), .items() for iteration.

Methods: update, pop, popitem, setdefault.

Dict comprehensions: {k: v*2 for k, v in d.items()}.

Merge: d1 | d2 (3.9+) creates new dict; |= updates in place.

Defaultdict, Counter, and OrderedDict in collections extend common patterns. For nested JSON, validate schema before deep access to avoid KeyError chains.

Keys must be hashable and stable while in the dict—do not use mutable lists as keys.

Insertion order is stable in 3.7+; manual counts.get(k,0)+1 patterns precede Counter in many scripts.

Using d[key] when key might be missing—prefer get or try/except.

Iterating for k in d then mutating size during loop without care.

Relying on KeyError for control flow in application logic.

Building huge dicts without considering memory—sometimes database or streaming fits better.

Use items() when you need both key and value in loops.

Normalize keys (e.g. lowercased strings) at the boundary when aggregating user input.

Serialize with json.dumps knowing only str keys and JSON-serializable values export cleanly.

Consider dataclasses.asdict or explicit schemas for complex nested models.

Use collections.defaultdict when missing keys are common and a default factory fits.

Re-read the examples below with these ideas in mind; change variable names and inputs to match your own project.

The program below demonstrates basics. Read the comments on each line, run the code, then change names or values to see how the output shifts.

# Example: Basics
# Run in the REPL or save as a .py file and execute with python.
person = {"name": "Ada", "age": 36}
person["role"] = "engineer"
print(person.get("phone", "n/a"))
print(person)

This sample walks through iterate in a small, runnable script. Paste it into the REPL or save it as a .py file before you continue to the next block.

# Example: Iterate
# Run in the REPL or save as a .py file and execute with python.
scores = {"math": 95, "cs": 99, "phys": 88}
for subj, val in scores.items():
    print(f"{subj:5} -> {val}")

Here is a hands-on illustration of merge & comprehension. Follow the inline comments first; only then execute the snippet and compare the result with what you expected.

# Example: Merge & comprehension
# Run in the REPL or save as a .py file and execute with python.
a = {"x": 1, "y": 2}
b = {"y": 20, "z": 3}
print(a | b)
print({k: v*2 for k, v in a.items()})

The program below demonstrates dict comprehension. Read the comments on each line, run the code, then change names or values to see how the output shifts.

# Build dicts from iterables with a comprehension
words = ["apple", "pie", "banana"]  # sample tokens
lengths = {w: len(w) for w in words}  # key->value per word
print(lengths)  # {'apple':5, ...}
scores = {"ada": 99, "grace": 97}  # base mapping
bonus = {k: v + 1 for k, v in scores.items()}  # transform values
print(bonus)  # incremented copy
for name, score in scores.items():  # iterate pairs
    print(name, score)  # two-column output
print(list(scores.keys()))  # dynamic view of keys
print("ada" in scores)  # membership on keys

This sample walks through merge mappings in a small, runnable script. Paste it into the REPL or save it as a .py file before you continue to the next block.

# Python 3.9+ | merges dicts into a new mapping
defaults = {"theme": "light", "lang": "en"}  # base config
overrides = {"theme": "dark", "zoom": 1.25}  # user prefs
config = defaults | overrides  # right side wins on conflicts
print(config)  # theme dark, lang en, zoom 1.25
config |= {"zoom": 1.5}  # in-place merge update
print(config["zoom"])  # 1.5
payload = dict([("a", 1), ("b", 2)])  # from pairs
print(payload.get("c", 0))  # safe missing key
payload.setdefault("c", 3)  # insert if absent
print(payload)  # includes c

« Python Sets All tutorials Python If Else »