Loop Idioms and Patterns
A for loop over a dictionary iterates through keys; to filter by value, use the index operator to retrieve each value and test it against a condition.
Try it: Loop Tracer
How a Python for loop visits each item in turn, and how an accumulator variable (a total, a count, a best-so-far or a result list) changes on every iteration.
How it works
- Initialise the accumulator before the loop.
- Each iteration, the loop variable takes the next value from the list.
- An if inside the loop decides whether to update the accumulator.
- After the last item the loop ends and the accumulator holds the answer.
Default run (13 steps): values = [4, 9, 2, 7, 5]. Run the loop one statement at a time. … The loop has used every value. print(total) shows 27.
Simplified: A model of five fixed loop programs (sum, count, maximum, minimum, filter) run on your list — it steps the program exactly as Python would, but it does not run Python.
Loading the simulation…
The Key-Value Puzzle
When a for loop iterates directly over a dictionary, the loop variable contains a key. That is useful when you want to work with keys, but it creates an extra step when your condition concerns values. To decide whether an entry qualifies, first use the key with the index operator to retrieve its corresponding value, then test that value.
What do you think happens?
A dictionary stores name counts. Which entries should pass a condition requiring a count greater than 10?
Reveal answer
Only entries whose stored value is greater than 10
The filtering condition is about each entry's value. The key helps retrieve that value, but the key itself is not what the condition tests.
From Key to Value
The index operator connects the loop variable to the value stored under that key. If the loop variable is key and the dictionary is counts, then counts[key] retrieves the value associated with the current key. The loop therefore follows three stages: obtain a key, retrieve its value with the index operator, and test the retrieved value with a condition.
counts = {
"Maya": 14,
"Luis": 12,
"Chuck": 1
}
for name in counts:
if counts[name] > 10:
print(name, counts[name])- 1The for statement assigns a dictionary key to name.
- 2counts[name] retrieves the value associated with that key.
- 3The if statement checks whether the retrieved value is greater than 10.
- 4Maya and Luis pass the test, so their entries are printed.
- 5Chuck has a count of 1, so its entry is skipped.
Maya 14
Luis 12The Filtering Path
For each key, the condition determines whether the loop body runs. A true comparison sends the entry into the body, where it can be printed or collected. A false comparison skips the body and lets the loop continue with the next key. The condition can use different comparison operators and data types; the essential pattern remains the same: iterate through keys, retrieve values, and test those values.
Before reading the output, predict which entries satisfy the value condition. Then trace one passing entry and one failing entry. This makes it easier to notice whether the condition is testing counts[name] or accidentally testing name.
Selecting Without Changing
| Operation | What happens to qualifying entries | Typical destination |
|---|---|---|
| Filtering | Existing key-value pairs that pass the condition are selected | Printed output, new dictionary, or list |
| Transforming | Entries are modified before they are stored or used | A result collection containing changed entries |
Filtering selects entries; transforming changes entries. The loop pattern in this article is primarily a filtering pattern.
In the filtering pattern, a qualifying entry is selected rather than altered. For example, adding counts[name] to a new dictionary preserves the key-value pair from the source dictionary. A separate operation could modify the collected dictionary later, but that would be different from deciding which entries pass the filter.
Collecting Qualifying Entries
counts = {
"Maya": 14,
"Luis": 12,
"Chuck": 1
}
filtered = {}
for name in counts:
if counts[name] > 10:
filtered[name] = counts[name]
selected_names = []
for name in counts:
if counts[name] > 10:
selected_names.append(name)- 1filtered starts as a new empty dictionary.
- 2When a value passes the condition, the original key and its value are assigned to filtered.
- 3After the loop, filtered contains only the passing entries.
- 4
selected_namesstarts as a new empty list. - 5When a value passes the condition, its key is appended to
selected_names. - 6The dictionary result retains key-value pairs, while the list result stores only the selected keys.
filtered is {"Maya": 14, "Luis": 12}
selected_names is ["Maya", "Luis"]Mistakes That Break the Pattern
Common mistake Comparing the key instead of the value
What it looks likeif name > 10:Why it failsDirect dictionary iteration supplies a key. In a name-count dictionary, the key is a name, not the numeric count being filtered.
Do this insteadRetrieve the value first: if counts[name] > 10:
Common mistake Forgetting the index operator
What it looks likeif name == 10:Why it failsThis compares the key with 10 instead of testing the value stored under that key.
Do this insteadUse the dictionary and current key together: counts[name]
Common mistake Using assignment instead of comparison
What it looks likeif counts[name] = 10:Why it failsThe filtering condition needs to compare a value with a threshold. Assignment and comparison are different operations.
Do this insteadUse a comparison operator such as == or > in the condition.
Common mistake Modifying the dictionary being iterated over
What it looks likeAdding or removing entries from counts inside the loop over counts
Why it failsThe source pattern iterates through a dictionary and collects passing entries in a separate result. Changing the dictionary during that iteration is a common mistake.
Do this insteadBuild a new dictionary for filtered results, then use or modify that result after the loop.
for name in counts:
if name > 10:
print(name)The condition attempts to test the key.
for name in counts:
if counts[name] > 10:
print(name)The condition retrieves and tests the value associated with the key.
Practice the Selection Pattern
Write a loop that examines a dictionary called scores and prints the keys whose values are less than 50. Then adapt the loop so it stores the passing key-value pairs in a new dictionary called low_scores.
Hints
- Iterating directly over scores gives you each key.
- Use scores[key] to retrieve the value for the current key.
- Use one condition for printing and assign the passing key-value pair to
low_scoresfor collection.
Tracing One Entry
Suppose the current key is Maya and counts[Maya] is 14. Decide whether the entry passes the condition counts[name] > 10.
- 1Receive the key
The loop variable name receives Maya.
- 2Retrieve the value
The index expression counts[name] retrieves 14.
- 3Test the condition
The comparison 14 > 10 is true.
- 4Run the loop body
Because the condition is true, the entry can be printed or added to a result collection.
The Maya entry passes the filter.
Pattern Summary
- 1A for loop that iterates directly over a dictionary supplies keys.
- 2Use the index operator, such as counts[key], to retrieve the value associated with the current key.
- 3Filter by testing the retrieved value, not by comparing the key directly.
- 4A passing entry can be printed immediately or collected in a new dictionary or list.
- 5Filtering selects existing entries; transforming changes entries before they are stored or used.
At a glance
- Direct dictionary iteration gives the loop variable a key.
- The index operator retrieves the value needed for a value-based condition.
- A true condition selects an entry; a false condition skips it.
- Filtered results can be printed, collected in a new dictionary, or collected as selected keys in a list.
- Do not confuse filtering with transforming, and avoid modifying the dictionary being iterated over.