A Python dictionary (dict) stores data as key: value pairs, so you look something up by name instead of by position. You write it with curly braces, for example {"name": "Asha", "marks": 90}, and read a value with d["name"]. Keys must be unique and unchangeable (hashable), values can be anything, and since Python 3.7 a dictionary remembers the order items were added.
This guide shows how to create, read, change and loop over dictionaries, with the patterns you will use most (counting, grouping, nesting) and the mistakes to avoid. Every output is real.
In this guide
The short version
- Create:
d = {"key": value}. Read:d["key"]or the saferd.get("key"). - Add or update:
d["key"] = value. Delete:d.pop("key")ordel d["key"]. - Loop with
d.items()to get keys and values together. - Keys are unique. A list cannot be a key, but a string, number or tuple can.
Creating and reading a dictionary
Think of a dictionary as a small table with two columns: the key you look up, and the value you get back. d[key] reads a value directly, and in checks whether a key exists. Notice that the last example keeps the order in which the items were written, not alphabetical order:
student = {"name": "Asha", "marks": 90, "city": "Pune"}
print(student["name"])
print(student.get("age"))
print(student.get("age", 18))
print(len(student), "city" in student)
d = {"b": 1, "a": 2}
print(list(d))
Output
Asha
None
18
3 True
['b', 'a']
d.get(key) returns None when the key is missing, and d.get(key, default) returns your default instead. Plain d[key] on a missing key is an error:
student = {"name": "Asha"}
print(student["age"])
Output
KeyError: 'age'
Use d[key] when the key must exist (a missing key is a real bug you want to hear about) and d.get(key) when a missing key is normal.
Adding, updating and deleting
Assigning to a key adds it if it is new and replaces the value if it already exists. update() does the same for several keys at once. pop() removes a key and hands back its value:
student = {"name": "Asha", "marks": 90}
student["city"] = "Pune"
student["marks"] = 95
student.update({"grade": "A", "marks": 96})
print(student)
removed = student.pop("city")
print(removed, student)
del student["grade"]
print(student)
Output
{'name': 'Asha', 'marks': 96, 'city': 'Pune', 'grade': 'A'}
Pune {'name': 'Asha', 'marks': 96, 'grade': 'A'}
{'name': 'Asha', 'marks': 96}
Look at the position of marks: updating an existing key does not move it. New keys are added at the end.
Looping over a dictionary
A plain for loop gives you the keys. Use .items() for key and value together, .keys() for just keys and .values() for just values:
scores = {"Asha": 90, "Ravi": 72, "Meera": 85}
for name in scores:
print(name)
for name, mark in scores.items():
print(name, "->", mark)
print(list(scores.keys()), list(scores.values()))
print(round(sum(scores.values()) / len(scores), 1))
Output
Asha
Ravi
Meera
Asha -> 90
Ravi -> 72
Meera -> 85
['Asha', 'Ravi', 'Meera'] [90, 72, 85]
82.3
Two patterns you will use constantly: counting and grouping
Counting
To count how often things appear, use get() with a default of 0. For this exact job the standard library also has collections.Counter, which does it in one line and can rank the results:
counts = {}
for ch in "banana":
counts[ch] = counts.get(ch, 0) + 1
print(counts)
from collections import Counter
print(Counter("banana"))
print(Counter("banana").most_common(1))
Output
{'b': 1, 'a': 3, 'n': 2}
Counter({'a': 3, 'n': 2, 'b': 1})
[('a', 3)]
Grouping
setdefault(key, default) returns the value for a key, first creating it with the default if it is missing. It is a neat way to group items into lists:
words = ["apple", "avocado", "banana", "blueberry", "cherry"]
groups = {}
for w in words:
groups.setdefault(w[0], []).append(w)
print(groups)
Output
{'a': ['apple', 'avocado'], 'b': ['banana', 'blueberry'], 'c': ['cherry']}
Dictionary comprehensions
Like list comprehensions, you can build a dictionary in one expression: {key: value for item in iterable if condition}.
squares = {n: n * n for n in range(1, 6)}
print(squares)
prices = {"pen": 10, "book": 150, "bag": 700}
expensive = {item: price for item, price in prices.items() if price > 100}
print(expensive)
Output
{1: 1, 2: 4, 3: 9, 4: 16, 5: 25}
{'book': 150, 'bag': 700}
We explain the pattern in more depth in Python List Comprehension Explained Simply.
Nested dictionaries
Values can be dictionaries or lists, which is how JSON data from web services looks once Python reads it. Chain the lookups to reach inside, and use get() with an empty dictionary as the default so a missing level does not crash your code:
users = {
"asha": {"city": "Pune", "skills": ["sql", "python"]},
"ravi": {"city": "Delhi", "skills": ["excel"]},
}
print(users["asha"]["skills"][1])
print(users.get("meera", {}).get("city", "unknown"))
Output
python
unknown
Merging and sorting
Since Python 3.9 the | operator merges two dictionaries, and the value from the right-hand side wins when a key is in both. The older {**a, **b} form does the same and works everywhere:
defaults = {"theme": "dark", "lang": "en"}
custom = {"lang": "hi"}
print(defaults | custom)
print({**defaults, **custom})
Output
{'theme': 'dark', 'lang': 'hi'}
{'theme': 'dark', 'lang': 'hi'}
A dictionary itself is not sorted, but you can sort its items and build a new dictionary from the result. This is the classic “rank by value” task:
scores = {"Asha": 90, "Ravi": 72, "Meera": 85}
ranked = sorted(scores.items(), key=lambda kv: kv[1], reverse=True)
print(ranked)
print(dict(ranked))
Output
[('Asha', 90), ('Meera', 85), ('Ravi', 72)]
{'Asha': 90, 'Meera': 85, 'Ravi': 72}
Common mistakes
Mistake 1: indexing a key that may not exist
Use get() or check in first, as shown at the top, instead of catching a KeyError after the fact.
Mistake 2: changing a dictionary while looping over it
Adding or removing keys during a loop raises an error:
d = {"a": 1, "b": 2}
for k in d:
d["c"] = 3
Output
RuntimeError: dictionary changed size during iteration
Loop over a copy of the keys instead, using list(d), and change the dictionary freely:
d = {"a": 1, "b": 2}
for k in list(d):
d[k + "2"] = d[k] * 10
print(d)
Output
{'a': 1, 'b': 2, 'a2': 10, 'b2': 20}
Mistake 3: dict.fromkeys() with a mutable value
dict.fromkeys(keys, []) puts the same list under every key. Changing one changes them all. Use a comprehension so each key gets its own list:
d = dict.fromkeys(["a", "b"], [])
d["a"].append(1)
print(d)
d2 = {k: [] for k in ["a", "b"]}
d2["a"].append(1)
print(d2)
Output
{'a': [1], 'b': [1]}
{'a': [1], 'b': []}
Mistake 4: using an unhashable key
Keys must be hashable, meaning they cannot change. Strings, numbers and tuples work. Lists, sets and other dictionaries do not. See Python List vs Tuple vs Set for why.
Method cheat sheet
| Task | Code | Notes |
|---|---|---|
| Read a value | d[key] | KeyError if the key is missing |
| Read safely | d.get(key, default) | Never raises an error |
| Add or replace | d[key] = value | |
| Add several | d.update(other) | Existing keys are overwritten |
| Remove and return | d.pop(key) | Add a default to avoid KeyError |
| Remove | del d[key] | KeyError if missing |
| Check for a key | key in d | Checks keys, not values |
| Loop key and value | for k, v in d.items() | |
| Number of items | len(d) | |
| Merge | a | b | Python 3.9 and later |
Try it yourself
Work out each answer first, then open the solution.
1. Count how many times each word appears in "to be or not to be".
Show solution
counts = {}
for w in "to be or not to be".split():
counts[w] = counts.get(w, 0) + 1
print(counts)
Output
{'to': 2, 'be': 2, 'or': 1, 'not': 1}2. Swap keys and values in {"a": 1, "b": 2}.
Show solution
d = {"a": 1, "b": 2}
print({v: k for k, v in d.items()})
Output
{1: 'a', 2: 'b'}This works only when the values are unique and hashable.
3. Given a dictionary of scores, find the name with the highest score.
Show solution
scores = {"Asha": 90, "Ravi": 72, "Meera": 85}
print(max(scores, key=scores.get))
Output
Ashamax() loops over the keys, and key=scores.get tells it to compare them by their values.
4. What does d.get("y") return for d = {"x": 1}, and what does d.get("y", 0) return?
Show solution
d = {"x": 1}
print(d.get("y"), d.get("y", 0), "y" in d)
Output
None 0 FalseRun these in our free Python compiler and try your own data.
Frequently asked questions
What is a dictionary in Python?
A dictionary is a collection of key: value pairs. You use a key to look up its value, instead of using a numeric position like in a list. It is written with curly braces, for example {"name": "Asha"}.
Are Python dictionaries ordered?
Yes. Since Python 3.7 a dictionary keeps the order in which keys were first added. It is insertion order, not sorted order, so use sorted() when you need sorting.
What is the difference between d[key] and d.get(key)?
d[key] raises a KeyError if the key is missing. d.get(key) returns None (or a default you provide) instead.
How do I check if a key exists in a dictionary?
Use the in operator: "city" in student. It checks keys, not values. To check values, use value in d.values().
How do I sort a dictionary by value?
Sort its items with a key function, then build a new dictionary: dict(sorted(d.items(), key=lambda kv: kv[1])). Add reverse=True for highest first.
Can a dictionary have duplicate keys?
No. Assigning to an existing key replaces its value. If you need several values per key, store a list under the key, as in the grouping example above.
Related reading
- Python List vs Tuple vs Set: Key Differences – and why only some types can be dictionary keys.
- Python List Comprehension Explained Simply – including dictionary comprehensions.
- Mutable vs Immutable Objects in Python – the idea behind the fromkeys trap.
- Python Data Types Explained With Examples – the full list of built-in types.
Run this code in your browser
The free Upskly compiler runs Python with nothing to install. Paste the example, change it and see what happens.
Stuck on a traceback?
AI Assist works inside the Python notebook, so you can ask about an error or a concept without leaving the cell.
Test yourself
Timed questions on Dictionaries, with an explanation for every answer.