Python Dictionaries
Data Types Focus
Python Dictionaries
Dictionaries map keys to values with O(1) lookups on average. Learn how to create, access, iterate, merge, and count responsibly.
Creating dictionaries
user = {"id": 42, "active": True} # literal
config = dict(debug=True, retries=3) # dict() with keyword args
empty = {} # NOT set() — {} is an empty dict
pairs = dict([("a", 1), ("b", 2)]) # from an iterable of key/value tuples
Keys are unique and hashable
Two rules define how dictionaries behave:
- Keys must be hashable — immutable types like strings, numbers, and tuples work; lists and dicts cannot be keys.
- Keys are unique — assigning an existing key overwrites its value rather than adding a duplicate.
{"a": 1, "a": 2} # {'a': 2} — the second value wins
["x"] # as a key -> TypeError: unhashable type: 'list'
Dictionaries preserve insertion order (guaranteed since Python 3.7).
Access and modification
user["id"] # 42 — KeyError if the key is missing
user.get("email") # None if missing (no error)
user.get("email", "unknown") # returns a default if missing
user["email"] = "a@b.com" # add or overwrite a key
user.setdefault("role", "viewer") # set only if absent, then return it
user.pop("email", None) # remove and return (default avoids KeyError)
del user["active"] # remove a key
Reach for .get() whenever a missing key is a normal case—it avoids wrapping lookups in try/except.
Checking membership and size
"id" in user # True — membership tests keys, not values
"admin" not in user # True
len(user) # number of key/value pairs
Iteration
for key in user: # iterating a dict yields its keys
...
for key, value in user.items(): # keys and values together
print(key, value)
for value in user.values(): # values only
...
.keys(), .values(), and .items() return views that reflect later changes to the dictionary automatically.
Common methods
| Method | Description |
|---|---|
| get(key, default) | Look up a key without raising KeyError |
| setdefault(key, default) | Return the value, inserting the default if absent |
| update(other) | Merge another dict or key/value pairs in place |
| pop(key, default) | Remove a key and return its value |
| items() | View of (key, value) pairs for iteration |
| keys() / values() | Live views of keys or values |
| clear() | Remove all entries |
Dictionary comprehensions
Build a dictionary from an iterable in one expression:
squares = {n: n * n for n in range(5)} # {0: 0, 1: 1, 2: 4, ...}
prices = {"pen": 2, "book": 9, "pin": 1}
cheap = {k: v for k, v in prices.items() if v < 5} # filter by value
inverted = {v: k for k, v in prices.items()} # swap keys and values
Merging
merged = {**defaults, **overrides} # unpacking (all versions)
merged = defaults | overrides # union operator (Python 3.9+)
defaults |= overrides # update in place (Python 3.9+)
When keys collide, the value from the right-hand dictionary wins.
Counting and grouping patterns
Two idioms handle the majority of real dictionary work:
from collections import Counter, defaultdict
# Count occurrences
Counter("mississippi") # {'i': 4, 's': 4, 'p': 2, 'm': 1}
# Group items by a key
groups = defaultdict(list)
for word in ["apple", "ant", "bee"]:
groups[word[0]].append(word) # {'a': ['apple', 'ant'], 'b': ['bee']}
defaultdict supplies a default value for missing keys, so you skip the setdefault boilerplate.
Next up in your learning path
Frequently Asked Questions
What is the difference between d[key] and d.get(key)?
d[key] raises KeyError if the key is missing, while d.get(key) returns None (or a default you supply) instead. Use bracket access when a missing key is a bug, and get() when absence is expected.
user = {"id": 42}
user["email"] # KeyError
user.get("email") # None
user.get("email", "n/a") # 'n/a'
Can a dictionary have duplicate keys?
No. Keys are unique. If you assign the same key twice, the later value replaces the earlier one, so the dictionary keeps only the final assignment.
{"a": 1, "a": 2} # {'a': 2} — the second value wins
What can be used as a dictionary key?
Any hashable (immutable) object: strings, numbers, booleans, and tuples of those. Lists, sets, and dictionaries are mutable and therefore unhashable, so they cannot be keys.
{(1, 2): "point"} # OK — tuple key
{[1, 2]: "point"} # TypeError: unhashable type: 'list'
Are Python dictionaries ordered?
Yes. Since Python 3.7 dictionaries preserve insertion order, so iteration returns keys in the order they were added. To deduplicate a list while keeping order, build a dict from it.
list(dict.fromkeys(["b", "a", "b", "c"])) # ['b', 'a', 'c']
How do I merge two dictionaries?
Use {**a, **b} on any version, or a | b on Python 3.9+. Both return a new dict where keys in b override matching keys in a. Use a |= b to merge in place.
a = {"x": 1, "y": 2}
b = {"y": 9, "z": 3}
a | b # {'x': 1, 'y': 9, 'z': 3}