SECTION 1
Historical Context & Motivation
Before modern programming languages gave us convenient data structures, programmers had to manually manage memory addresses to store and retrieve related pieces of information. The idea of a dictionary — a collection that maps unique keys to values — arose from the need to look up data quickly, much like finding a word's definition in a physical dictionary. As programs grew more complex, developers needed ways to not only store data in these structures but also iterate over every entry to compute totals, filter results, and transform information.
1960s • Associative Arrays Emerge
1991 • Python 1.0 Released
dict type, making key-value storage a first-class feature of the language.2001 • Iterators Protocol (PEP 234)
for key in my_dict: instead of looping over a separate list of keys.2008 • Python 3 & Dictionary Views
.keys(), .values(), and .items() with memory-efficient view objects, making dictionary iteration faster and more Pythonic.2017 • Ordered by Default (Python 3.7)
The core question this lesson answers is straightforward: once you have data stored in a dictionary, how do you systematically visit every key, every value, or every key-value pair to compute a result? Whether you are calculating a grade average, counting word frequencies, or summarizing a shopping cart, the answer lies in dictionary iteration.
SECTION 2
Core Principles & Definitions
A Python dictionary stores data as key-value pairs. Each key is unique and maps to exactly one value. When we iterate over a dictionary, we use a for loop to visit entries one at a time. Python gives us three main approaches, each suited to different tasks.
Iterating Over Keys
for key in my_dict: loops through every key. You can then use my_dict[key] inside the loop to access the corresponding value.Iterating Over Values
for value in my_dict.values(): when you only need the values and do not care about the keys. This is common for summing or averaging numeric data.Iterating Over Items
for key, value in my_dict.items(): to unpack both the key and the value simultaneously. This is the most versatile approach for computing results.Accumulating Results
KEY TAKEAWAY
SECTION 3
Visual Explanation — How Dictionary Iteration Works
grades. The top-center box shows what the loop variable receives when iterating over keys alone. The top-right box shows iterating over .values(). The bottom panel demonstrates .items(), which unpacks both the key and value on every iteration.As the diagram shows, the default for key in grades: loop hands you one key per iteration. If you need the corresponding value, you look it up with grades[key]. The .values() method skips keys entirely and gives you each value directly. Finally, .items() returns tuples of (key, value) that you can unpack into two loop variables. Choosing the right method depends on which pieces of data your computation actually needs.
SECTION 4
How Dictionary Iteration Works Under the Hood
Although you do not need to understand every internal detail, knowing a few things about how Python processes a for loop over a dictionary helps you write better code. When Python encounters for key in my_dict:, it calls the dictionary's iterator behind the scenes. The iterator keeps track of where it is in the dictionary's internal table and serves up the next key each time the loop cycles.
The General Accumulator Pattern
Most tasks that involve iterating a dictionary follow a common structure called the accumulator pattern. You initialize a variable before the loop, update it inside the loop body, and then use it after the loop finishes. The pattern looks like this in pseudocode:
ACCUMULATOR PATTERN
The initial_value is often 0 (for sums), an empty list (for filtering), or an empty string (for building output). The update step combines the current accumulator with data from the current iteration.
Common Computation Recipes
SUM ALL VALUES
After the loop, total holds the sum of every value in the dictionary.
COUNT ENTRIES MATCHING A CONDITION
This counts how many items in inventory have a value less than 10. The if statement inside the loop acts as a filter.
FIND THE KEY WITH THE MAXIMUM VALUE
After the loop, best_key holds the key associated with the highest value. We start best_val at negative infinity so that any real value will be larger.
SECTION 5
Dictionary Iteration Methods — A Closer Look
| Method | Syntax | What Each Iteration Yields | Best Used When… |
|---|---|---|---|
| Keys (default) | for k in d: | One key at a time | You need to look up or check keys; you can still access values via d[k] |
.keys() | for k in d.keys(): | One key at a time (explicit) | You want to make it crystal clear you are looping over keys, or you need set operations on the view |
.values() | for v in d.values(): | One value at a time | You only need the values — e.g., summing prices, averaging scores |
.items() | for k, v in d.items(): | A (key, value) tuple, unpacked into two variables | You need both the key and the value together — the most versatile option |
The four main ways to iterate over a Python dictionary
.values(). If you need both keys and values, use .items(). If you only need keys, the default loop or .keys() will do.Important Rule
RuntimeError. If you need to modify the dictionary, build a list of changes first and apply them after the loop.SECTION 6
Worked Example — Computing a Class Average
Suppose you have a dictionary that maps student names to their exam scores. Your task is to calculate the class average and identify the top scorer. Let's walk through this step by step.
Calculate Class Average & Top Scorer
- 1
Step 1 — Define the Dictionary
We start with the dictionary of student scores:grades = {"Alice": 92, "Bob": 85, "Carol": 97, "Dan": 78}This dictionary has 4 key-value pairs.Dictionary created with 4 entries. - 2
Step 2 — Initialize Accumulator Variables
We need a running total and a way to track the highest score:total = 0 best_name = "" best_score = 0These accumulators will be updated inside the loop.total = 0,best_score = 0 - 3
Step 3 — Iterate with .items()
We loop through the dictionary using.items()because we need both the name (key) and the score (value):for name, score in grades.items(): total += score if score > best_score: best_score = score best_name = nameOn each iteration,totalgrows by the current score, and we check whether the current score beats the previous best.After iteration:total = 352,best_name = "Carol",best_score = 97 - 4
Step 4 — Compute the Average
Divide the total by the number of entries. We uselen(grades)to get the count:average = total / len(grades)Here, 352 ÷ 4 = 88.0.average = 88.0 - 5
Step 5 — Display the Results
Finally, print the computed results:print(f"Class average: {average}") print(f"Top scorer: {best_name} with {best_score}")Output:Class average: 88.0 Top scorer: Carol with 97Average = 88.0, Top scorer = Carol (97)
SECTION 7
Comparing Dictionary Iteration Approaches
You might wonder when to use each iteration method, or how dictionary iteration compares to iterating over other data structures. The table below highlights key trade-offs and use cases.
| Approach | Strengths | Limitations |
|---|---|---|
for k in dict: | Simple and concise; good when you mainly need keys and only occasionally look up values | Requires an extra lookup (dict[k]) every time you need a value |
.values() | Perfect for aggregation tasks (sum, average, min, max) when keys are irrelevant | You lose track of which key each value belongs to |
.items() | Most flexible — gives both key and value with no extra lookup; clean tuple unpacking | Slightly more verbose syntax; may be unnecessary if you truly only need keys or only values |
| List iteration for comparison | Lists are ordered by index and support slicing; simpler when you just have a sequence of items | No built-in key-value pairing; looking up a specific element requires knowing its index or searching |
Comparison of dictionary iteration methods and list iteration
KEY TAKEAWAY
.items(). It is like getting both a menu item name and its price at the same time — you have all the information you need and can decide in the loop body what to do with it. Reserve .values() for pure number-crunching tasks where the keys truly do not matter.SECTION 8
Connection to Advanced Concepts
Once you are comfortable iterating dictionaries with basic for loops, you will encounter more advanced Python features that build on the same foundation. The table below previews where this knowledge leads.
| What You Know Now | What Comes Next |
|---|---|
Accumulating a sum with a for loop | Using built-in sum(), min(), max() on dictionary views for one-line aggregation |
Filtering inside a loop with if | Dictionary comprehensions — building a new filtered dictionary in a single expression |
| Iterating one dictionary at a time | Merging and comparing two dictionaries; using collections.Counter for frequency analysis |
| Flat key-value pairs | Nested dictionaries — dictionaries whose values are themselves dictionaries, requiring nested iteration |
How basic dictionary iteration connects to future topics
These advanced features are powerful, but they all rely on the fundamental skill you are building right now: systematically visiting every key-value pair and doing something useful with each one. Master the basic loop patterns first, and the more concise syntax will feel natural when you encounter it.
SECTION 9
Practice Problems
Question 1: CONCEPTUAL
for k in d: and iterating with for k, v in d.items():. When would you prefer one over the other?Show answer
for k in d:, the loop variable k receives only the key on each iteration. If you need the value, you must look it up manually with d[k]. With for k, v in d.items():, both the key and value are unpacked automatically. Use the default key loop when you primarily need keys, and use .items() when you need both pieces of data, as it is more readable and avoids redundant lookups.Question 2: BASIC CALCULATION
prices = {"apple": 1.20, "banana": 0.50, "cherry": 2.00}, write a loop that computes the total cost of all items. What is the final value of total?Show answer
total = 0, then iterate: for price in prices.values(): total += price. On the first pass, total becomes 1.20; then 1.70; then 3.70. The final value of total is 3.70. We used .values() because we only needed the numeric prices, not the fruit names.Question 3: INTERMEDIATE
temps = {"Mon": 72, "Tue": 68, "Wed": 75, "Thu": 80, "Fri": 65}, write code that builds a new list called hot_days containing only the day names where the temperature was 72 or higher.Show answer
hot_days = []. Then iterate: for day, temp in temps.items(): if temp >= 72: hot_days.append(day). The loop checks each day's temperature. Monday (72), Wednesday (75), and Thursday (80) all meet the condition, so hot_days becomes ["Mon", "Wed", "Thu"]. We used .items() because we needed both the day name (to append) and the temperature (to compare).Question 4: APPLIED
stock = {"pencil": 120, "eraser": 45, "notebook": 8, "pen": 3, "ruler": 60}. Write code that (a) counts how many items have fewer than 10 in stock, and (b) prints the names of those items. Show the expected output.Show answer
low_count = 0. Then: for item, qty in stock.items():
if qty < 10:
print(item)
low_count += 1. The items with fewer than 10 units are "notebook" (8) and "pen" (3), so the output prints those two names and low_count ends up as 2. This combines filtering (the if condition) with the accumulator pattern (counting matches).Question 5: CRITICAL THINKING
test1 = {"Alice": 88, "Bob": 76, "Carol": 95} and test2 = {"Alice": 92, "Bob": 81, "Carol": 89} — write code that creates a new dictionary averages where each key is a student name and each value is that student's average of the two tests. Then find and print the name of the student with the highest average.Show answer
averages = {}. Iterate over one dictionary and look up the matching key in the other: for name, score1 in test1.items():
averages[name] = (score1 + test2[name]) / 2. This produces {"Alice": 90.0, "Bob": 78.5, "Carol": 92.0}. To find the top student, iterate again: top = ""
top_avg = 0
for name, avg in averages.items():
if avg > top_avg:
top_avg = avg
top = name
print(top). The output is "Carol" with an average of 92.0. This problem synthesizes dictionary creation, iteration with .items(), cross-dictionary lookup, and the max-finding accumulator pattern.SUMMARY
Lesson Summary
Summary
Python dictionaries store data as key-value pairs, and iterating over them is one of the most common operations in programming. You can loop over keys using for k in d:, over values using .values(), or over both simultaneously using .items() with tuple unpacking. The choice depends on which pieces of data your task requires.
The accumulator pattern — initialize before the loop, update inside the loop, use after the loop — is the backbone of computing results from dictionary data. Whether you are calculating a sum, finding a maximum, filtering entries, or building a new data structure, the accumulator pattern gives you a reliable framework. Master these patterns, and you will be well-prepared for dictionary comprehensions, nested dictionaries, and other advanced Python features.