Python Iterating Through Dictionaries

In the last lesson, we learned about Python Dictionary Comprehensions. Now let’s loop through dictionary keys, values, and key-value pairs.

Let’s Talk About Going Through a Dictionary

We have a dictionary. It has keys and values. Now we want to go through it. Look at each item. Maybe print them. Maybe do some calculation. Maybe build a new list.

That is what iterating means. Going through each item one by one.

Python gives us several ways to iterate through a dictionary. Let’s look at them.

Looping Through Keys in Python

By default, when we loop through a dictionary, we get the keys.

person = {"name": "Alex", "age": 25, "city": "London"}
for key in person:
print(key)

Output

name
age
city

That is the simplest way. Just a for loop. We get each key.

We can also use the .keys() method explicitly.

for key in person.keys():
print(key)

Same output. The .keys() method returns a view of all keys. And looping over it gives us the same thing.

But since looping over the dictionary directly gives keys, we do not need .keys() unless we want to be explicit.

Looping Through Values in Python

If we only care about the values, we use .values().

person = {"name": "Alex", "age": 25, "city": "London"}
for value in person.values():
print(value)

Output

Alex
25
London

That gives us each value. No keys. Just the values.

Looping Through Keys and Values Together in Python

The most common way to iterate through a dictionary is with .items(). It gives us both the key and the value at the same time.

person = {"name": "Alex", "age": 25, "city": "London"}
for key, value in person.items():
print(f"{key}: {value}")

Output

name: Alex
age: 25
city: London

That is clean and easy. We unpack each item into key and value.

This is the method we will use most of the time. Because usually we want both.

Accessing Values Inside a Key Loop in Python

We can loop through keys and then use the key to get the value.

person = {"name": "Alex", "age": 25, "city": "London"}
for key in person:
print(f"{key}: {person[key]}")

Output

name: Alex
age: 25
city: London

That works. But it is a bit slower than using .items(). Because we have to look up each value by key.

So if we need both, let’s use .items(). It is faster and cleaner.

Iterating with enumerate in Python

Sometimes we want the index as well. Like if we want to number the items.

person = {"name": "Alex", "age": 25, "city": "London"}
for index, (key, value) in enumerate(person.items(), 1):
print(f"{index}. {key}: {value}")

Output

1. name: Alex
2. age: 25
3. city: London

The enumerate function adds a counter. We start it at 1. And we unpack the item into key and value.

That is handy when we want to display a numbered list.

Iterating in a Specific Order in Python

Dictionaries in Python 3.7 and later remember the order in which items were inserted. So if we iterate, we get them in that order.

person = {"name": "Alex", "age": 25, "city": "London"}
for key in person:
print(key)

Output

name
age
city

That is the insertion order. If we had added “city” first, it would appear first.

If we want a different order, we can sort the keys.

for key in sorted(person):
print(f"{key}: {person[key]}")

Output

age: 25
city: London
name: Alex

That sorts the keys alphabetically. And then we access the values.

Modifying a Dictionary While Iterating in Python

This is a big no-no. We cannot change the size of a dictionary while iterating over it. Python will raise a RuntimeError.

person = {"name": "Alex", "age": 25, "city": "London"}
for key in person:
if key == "age":
del person[key] # Error!

Output

RuntimeError: dictionary changed size during iteration

We cannot add or remove items while iterating. We can change values, but not add or remove keys.

If we need to modify the dictionary, we iterate over a copy of the keys.

for key in list(person.keys()):
if key == "age":
del person[key]

That works. Because we are iterating over a list, not the dictionary itself.

Or we can build a new dictionary.

new_person = {k: v for k, v in person.items() if k != "age"}

That is often cleaner.

Python Iterating Through Dictionaries: A Real-Life Example

Let’s say we have a dictionary of student scores. And we want to print each student and their score. And also calculate the average.

scores = {"Alex": 85, "Sam": 92, "John": 78, "Emma": 95}
total = 0
for name, score in scores.items():
print(f"{name}: {score}")
total += score
average = total / len(scores)
print(f"Average: {average:.1f}")

Output

Alex: 85
Sam: 92
John: 78
Emma: 95
Average: 87.5

That is a typical use case.

Another Example — Filtering

scores = {"Alex": 85, "Sam": 92, "John": 78, "Emma": 95}
passed = {}
for name, score in scores.items():
if score >= 80:
passed[name] = score
print(passed)

Output

{'Alex': 85, 'Sam': 92, 'Emma': 95}

That builds a new dictionary with only the students who passed.

We could also do this with a dictionary comprehension.

passed = {name: score for name, score in scores.items() if score >= 80}

Same result. Cleaner.

Common Mistakes with Python Iterating Through Dictionaries

Mistake 1: Trying to Modify the Dictionary While Iterating

for key in person:
if key == "age":
del person[key] # Error!

So what do we do? We iterate over a copy of the keys, or build a new dictionary.

Mistake 2: Using the Wrong Method

for value in person: # This gives keys, not values
print(value)

If we want values, we use .values(). If we want both, we use .items().

Mistake 3: Forgetting That .items() Gives Tuples

for item in person.items():
print(item) # prints ('name', 'Alex')

If we want to unpack, we use for key, value in person.items().

Mistake 4: Assuming Order in Older Python Versions

In Python 3.6 and earlier, dictionaries did not preserve insertion order. If we are using an older version, let’s not rely on order. We use sorted() if we need a specific order.

Next, we will learn about Python Exceptions and handle errors without crashing the program.