How to loop through a dictionary in Python
Learn how to loop through a Python dictionary. Explore different methods, tips, real-world applications, and common errors to avoid.

To iterate through a Python dictionary is a fundamental skill for any developer. This process is essential for accessing, managing, and manipulating the key-value pairs that structure your data.
In this article, you'll explore several powerful techniques for dictionary iteration, from simple for loops to more advanced methods. You will also find practical tips, examine real-world applications, and receive clear debugging advice.
Basic iteration through a dictionary
my_dict = {"apple": 1, "banana": 2, "cherry": 3}
for key in my_dict:
print(f"Key: {key}, Value: {my_dict[key]}")--OUTPUT--Key: apple, Value: 1
Key: banana, Value: 2
Key: cherry, Value: 3
The simplest way to loop through a dictionary is by using a for loop directly on the dictionary object. By default, this process iterates over the dictionary's keys. This is Python's most direct method for accessing each key sequentially.
Inside the loop, you can retrieve the corresponding value using standard square bracket notation, as seen with my_dict[key]. This pattern is efficient for tasks where you primarily need to work with the keys but also require access to their associated values.
Common dictionary iteration methods
For more granular control, Python's dedicated keys(), values(), and items() methods let you iterate through specific parts of your dictionary.
Using the keys() method explicitly
my_dict = {"apple": 1, "banana": 2, "cherry": 3}
for key in my_dict.keys():
print(f"The key is: {key}")--OUTPUT--The key is: apple
The key is: banana
The key is: cherry
While looping directly over a dictionary also gives you its keys, using the keys() method is more explicit. It clearly signals your intention to work only with the keys. This method returns a special "view object" that provides a dynamic look at the dictionary's keys.
- Readability: Using
.keys()can make your code's purpose clearer to others. - Dynamic updates: The view object isn't a static list; it reflects any additions or removals from the dictionary's keys in real time.
Looping through values with the values() method
my_dict = {"apple": 1, "banana": 2, "cherry": 3}
for value in my_dict.values():
print(f"The value is: {value}")--OUTPUT--The value is: 1
The value is: 2
The value is: 3
When your focus is solely on the dictionary's values, the values() method is the most direct approach. It lets you iterate over all values without involving their corresponding keys. This is particularly useful for value-centric operations.
- Common Uses: It's ideal for tasks like finding the total sum of numeric values or checking if a certain value exists in the dictionary.
Unpacking key-value pairs with the items() method
my_dict = {"apple": 1, "banana": 2, "cherry": 3}
for key, value in my_dict.items():
print(f"{key} has a value of {value}")--OUTPUT--apple has a value of 1
banana has a value of 2
cherry has a value of 3
The items() method is the most efficient way to loop through a dictionary when you need both the key and its value. It returns a view object where each item is a key-value pair. This allows you to unpack each pair directly into two variables within the for loop.
- Efficiency: This approach is faster than iterating through keys and then looking up each value separately.
- Readability: The
for key, value in my_dict.items()syntax is clean, intuitive, and considered highly Pythonic. You get direct access to both elements in one go.
Advanced dictionary operations
Building on these fundamental methods, you can use more advanced techniques to create new dictionaries, filter them during iteration, and work with dynamic dictionary views.
Creating a new dictionary with dictionary comprehension
my_dict = {"apple": 1, "banana": 2, "cherry": 3}
doubled_values = {k: v*2 for k, v in my_dict.items()}
print(doubled_values)--OUTPUT--{'apple': 2, 'banana': 4, 'cherry': 6}
Dictionary comprehension offers a compact and readable way to create a new dictionary from an existing one. It’s a one-liner that combines a for loop with the logic for creating new key-value pairs, all wrapped in curly braces.
- Syntax: The expression
{k: v*2 for k, v in my_dict.items()}iterates through each key-value pair, keeps the original keyk, and creates a new value by multiplying the original valuevby 2. - Efficiency: This method is often more efficient and Pythonic than creating an empty dictionary and populating it with a traditional
forloop.
Working with dynamic dictionary view objects
my_dict = {"apple": 1, "banana": 2, "cherry": 3}
keys_view = my_dict.keys()
my_dict["date"] = 4
print(f"Updated keys view: {keys_view}")--OUTPUT--Updated keys view: dict_keys(['apple', 'banana', 'cherry', 'date'])
The methods keys(), values(), and items() don't return a static list; they provide a dynamic view of the dictionary's contents. This view acts as a live window into your dictionary's data, reflecting changes as they happen.
- Live Updates: If you modify the dictionary, the view object updates instantly. You don't need to call the method again to see the changes.
- Example in Action: After you run
my_dict["date"] = 4, thekeys_viewyou created earlier automatically includes the new key "date." This ensures you're always working with the most current data.
Filtering dictionaries during iteration
my_dict = {"apple": 1, "banana": 2, "cherry": 3, "date": 4}
filtered_dict = {k: v for k, v in my_dict.items() if v % 2 == 0}
print(filtered_dict)--OUTPUT--{'banana': 2, 'date': 4}
You can easily filter a dictionary by adding an if condition directly inside a dictionary comprehension. This creates a new dictionary containing only the key-value pairs that meet your criteria, making your code both compact and efficient.
- The expression
if v % 2 == 0acts as the filter. It uses the modulo operator (%) to check if a value is evenly divisible by two. - Only pairs where the condition is true—in this case, where the value is even—are included in the final
filtered_dict.
Move faster with Replit
Replit is an AI-powered development platform that transforms natural language into working applications. Describe what you want to build, and Replit Agent creates it—complete with databases, APIs, and deployment.
For the dictionary iteration techniques we've explored, Replit Agent can turn them into production-ready tools.
- Build an inventory management system that uses the
items()method to update stock levels for each product. - Create a user role dashboard that filters a dictionary to display users with specific permissions.
- Deploy a data transformation utility that uses dictionary comprehension to convert product prices from one currency to another.
Describe your app idea, and Replit Agent writes the code, tests it, and fixes issues automatically, all in your browser.
Common errors and challenges
Navigating dictionary iteration can sometimes lead to errors like KeyError or RuntimeError, but these common pitfalls are easy to avoid.
Preventing KeyError when accessing dictionary keys
A KeyError is one of the most frequent issues you'll encounter. It happens when you try to access a key that doesn't exist in the dictionary. Instead of letting your program crash, you can handle these situations gracefully.
- Use the
get()method. Instead ofmy_dict['non_existent_key'], usemy_dict.get('non_existent_key'). If the key is missing, this method returnsNoneby default instead of raising an error. - You can also provide a default value to
get(), likemy_dict.get('non_existent_key', 0). This is perfect for situations where you need a fallback, such as incrementing a counter that may not have been initialized yet.
Avoiding RuntimeError when modifying during iteration
Python doesn't allow you to change the size of a dictionary—by adding or removing keys—while you're iterating over it. Doing so will trigger a RuntimeError: dictionary changed size during iteration. The dictionary's internal structure is disrupted, and the loop can no longer proceed safely.
- To get around this, you should iterate over a copy of the dictionary's keys or items. This leaves the original dictionary free to be modified.
- You can create a temporary list of the keys with
list(my_dict.keys())or create a shallow copy of the dictionary withmy_dict.copy()to loop over.
Using dict.update() or ** for merging dictionaries
Combining two dictionaries is a common task, but doing it inside a loop can be inefficient. Python offers better ways to merge them.
- The
update()method merges the keys and values from one dictionary into another. If there are overlapping keys, the values from the dictionary being merged in will overwrite the existing ones. - For a more modern and often more readable approach, you can use the dictionary unpacking operator
**. The expressionmerged_dict = {**dict1, **dict2}creates a new dictionary containing all items from both, with values fromdict2taking precedence in case of a key collision.
Preventing KeyError when accessing dictionary keys
A KeyError is one of the most common issues you'll face with dictionaries. It happens when you try to access a key that doesn't exist, which can immediately crash your program. This is a frequent bug in data processing tasks.
The following code snippet demonstrates exactly how this error occurs when you request a missing key like "email" from the user_data dictionary.
user_data = {"name": "John", "age": 30}
email = user_data["email"] # This raises KeyError
print(f"User email: {email}")
The user_data dictionary contains keys for "name" and "age", but not for "email". Attempting to access user_data["email"] directly results in the KeyError. The next example shows how to avoid this common runtime crash.
user_data = {"name": "John", "age": 30}
email = user_data.get("email", "Not provided")
print(f"User email: {email}") # Outputs: User email: Not provided
To prevent a KeyError, use the get() method. It safely retrieves a key's value. If the key, like "email", doesn't exist, it returns a default value—in this case, "Not provided"—instead of crashing your program. It's a reliable way to handle optional dictionary keys, especially when working with data from external sources where certain fields might be missing. This ensures your code runs smoothly without unexpected interruptions.
Avoiding RuntimeError when modifying during iteration
It's a common pitfall: trying to change a dictionary's size by adding or removing keys while looping through it. Python won't allow this and will raise a RuntimeError to avoid unpredictable outcomes. See this error in action in the code below.
numbers = {"a": 1, "b": 2, "c": 3, "d": 4}
for key in numbers:
if numbers[key] % 2 == 0:
del numbers[key] # RuntimeError: dictionary changed during iteration
The code fails because it tries to delete items with del numbers[key] while still looping over the dictionary. This size change is not allowed mid-iteration. The following example shows the correct way to handle this task.
numbers = {"a": 1, "b": 2, "c": 3, "d": 4}
keys_to_delete = [k for k, v in numbers.items() if v % 2 == 0]
for key in keys_to_delete:
del numbers[key]
print(numbers) # {'a': 1, 'c': 3}
The solution is to separate finding keys from deleting them. First, you create a new list, keys_to_delete, holding only the keys you want to remove. This is done using a list comprehension that iterates over the dictionary's items(). Then, you loop through this new, separate list and use del to remove each key from the original dictionary. This avoids the error because the dictionary isn't being modified during the initial iteration.
Using dict.update() or ** for merging dictionaries
When you need to combine two dictionaries, your first instinct might be to use the + operator, just as you would with lists or strings. This intuitive step, however, doesn't apply to dictionaries and will raise a TypeError. The following code demonstrates this common error.
dict1 = {"a": 1, "b": 2}
dict2 = {"b": 3, "c": 4}
merged = dict1 + dict2 # TypeError: unsupported operand type(s) for +
The + operator isn't defined for dictionaries because it offers no clear way to handle overlapping keys like "b". Python requires a more explicit approach to merging. The next example demonstrates a proper solution.
dict1 = {"a": 1, "b": 2}
dict2 = {"b": 3, "c": 4}
merged = {**dict1, **dict2} # Python 3.5+
print(merged) # {'a': 1, 'b': 3, 'c': 4}
The solution uses the dictionary unpacking operator ** to merge dict1 and dict2. This operator unpacks each dictionary's key-value pairs into a new one. When keys overlap, like "b", the value from the second dictionary (dict2) takes precedence, overwriting the first. It's a clean and readable way to combine dictionaries, especially when you need to merge data from multiple sources or update settings. This behavior makes it predictable and powerful.
Real-world applications
Now that you can iterate safely, you can apply these skills to real-world tasks like counting word frequencies and calculating grade averages.
Counting word frequency with the split() method
You can count word frequencies in a text by first using the split() method to break a string into individual words, then iterating through them to build a dictionary of their counts.
text = "the quick brown fox jumps over the lazy dog"
word_count = {}
for word in text.split():
if word in word_count:
word_count[word] += 1
else:
word_count[word] = 1
print(word_count)
This logic efficiently tallies word occurrences from a string. It iterates over each word from text.split() and uses a conditional check to populate the word_count dictionary.
- The expression
if word in word_countdetermines if the word is already a key. - If it is, the code increments the existing count with
+= 1. - If it’s a new word, it’s added to the dictionary with an initial count of
1.
This pattern is a fundamental way to count unique items in any Python sequence.
Calculating grade averages with nested dictionary iteration
Iterating through a nested dictionary lets you process structured data, like calculating each student's average grade from a digital grade book.
The outer loop unpacks each student's name and their subjects dictionary using grade_book.items(). Inside this loop, a second operation takes place on the inner dictionary to calculate the average.
- The
sum()function is called onsubjects.values()to add up all of a student's grades. - That total is then divided by the number of subjects, which is determined with
len(subjects). - An f-string formats the output, using
:.2fto round the final average to two decimal places.
grade_book = {
'Alice': {'math': 90, 'science': 82, 'history': 88},
'Bob': {'math': 85, 'science': 94, 'history': 76},
'Charlie': {'math': 92, 'science': 88, 'history': 91}
}
for student, subjects in grade_book.items():
total = sum(subjects.values())
average = total / len(subjects)
print(f"{student}'s average grade: {average:.2f}")
This code showcases a practical use for nested dictionaries by organizing student data. The outer dictionary acts as a roster, with each student's name mapping to an inner dictionary containing their grades.
- The
forloop processes this two-level structure, calculating an average grade for each student. - This approach keeps related data neatly bundled, making it easy to manage individual records within a larger dataset. It's a common pattern when working with structured information, such as data from a JSON file.
Get started with Replit
Turn your new skills into a real application. Describe what you want to build to Replit Agent, like “a tool that converts a dictionary of user data to a CSV” or “a script that calculates grade averages from a JSON file”.
Replit Agent will write the code, test for errors, and deploy your application directly from your browser. Start building with Replit.
Create and deploy websites, automations, internal tools, data pipelines and more in any programming language without setup, downloads or extra tools. All in a single cloud workspace with AI built in.
Create & deploy websites, automations, internal tools, data pipelines and more in any programming language without setup, downloads or extra tools. All in a single cloud workspace with AI built in.



%2520in%2520Python.png)