Modifying Lists During Iteration
For loops are the most common and natural way to iterate through list elements, using identical syntax to string iteration.
Try it: What a for Loop Hands You
What a Python for loop gives its loop variable from each kind of iterable: the characters of a string, the positions from range(len(word)), the elements of a list, (index, item) pairs from enumerate(), the numbers of range(start, stop, step), a dict's keys, its .values() and its .items() tuples unpacked into key, val, the inner lists of a nested list and the values an inner loop visits; and why removing items from a list while looping over it skips the next item, while looping over a copy nums[:] does not.
How it works
- The for statement asks the object for an iterator, then calls next() on it once per pass.
- Each next() result is bound to the loop variable (a tuple result such as ('a', 10) or (0, 'red') is unpacked into two names), and the indented body runs once with it.
- A string gives characters, a list gives element values (not positions), range() computes start, start + step, … stopping before stop, and a dict gives its keys in insertion order (.values() the values, .items() key-value tuples).
- A nested list's inner list is one element of the outer loop; a second, inner for loop is needed to visit the values inside it.
- A list iterator only remembers a position number into the live list: removing an item shifts the later items left, so the item that slides into the passed position is skipped. Looping over a copy (nums[:]) keeps the positions fixed.
- When next() has nothing left the loop ends (StopIteration) and the loop variable keeps its last value; an empty iterable runs the body zero times.
Default run (10 steps): A 3-line program. Step through it: each pass of the for loop asks the iterator for its next item, binds the loop variable to it and runs the indented body once. … Done: the loop body ran 3 times. Output: red | green | blue.
Simplified: The programs are twelve fixed templates: you choose the loop and edit only its data (a short string, list items that are words or integers, key: value pairs with word keys and integer values, range numbers from -20 to 20, up to 4 rows of integers, up to 10 numbers). Nothing you type is executed: the lab's own small parsers turn it into literals, and a model of CPython's iterator protocol written for these loops runs the program. Every program was also run in CPython 3.12 under sys.settrace, and the lab reproduces the variables before every line, the printed output, the final variables and the error.
Loading the simulation…
One Element at a Time
When a list contains several items, a for loop provides a natural way to visit each item in turn. The loop assigns one list element to the loop variable for each iteration, then continues through the list. This is different from manually asking for one element at a time by index.
The loop variable contains the actual element value, not the element's index.
Following the List Positions
Imagine the loop moving from the first position of the list to the next position, visiting each position in order. At every position, the loop variable receives the value stored there. The loop body then works with that value. If the list has three elements, the loop body receives three element values, one per iteration.
A loop variable is the name that receives the current list element during an iteration. It is not automatically the numeric position of that element.
Reading Each Element
The syntax for iterating over a list uses the same general form as iteration over a string: choose a loop variable, provide the list, and place the work to perform inside the loop body. For a list of items, the loop variable receives the first item, then the second item, and so on until the elements have been visited.
red
green
blueThe first iteration assigns red to color, the second assigns green, and the third assigns blue. The loop variable therefore gives the loop body the values themselves. If the positions are needed instead, the source pack identifies range(len(list)) as the alternative approach.
Nested Lists Stay Whole
A nested list is still one element of its outer list. When a for loop iterates over the outer list, it visits the nested list as a whole rather than automatically visiting the values inside that nested list.
For example, if an outer list contains an inner list, the outer loop has one iteration in which the loop variable holds that inner list. The inner values are not separate outer-loop iterations.
When the List Is Empty
An empty list contains no elements to visit. Consequently, the loop body runs zero times. This is expected behavior, not an error: the loop receives a valid list, but there is no element to assign to the loop variable.
No outputWhat Modification Means Here
The source material establishes how a for loop traverses list elements, including empty and nested lists. It does not specify the detailed behavior of adding, removing, or changing list elements while that traversal is in progress. Therefore, do not use the traversal rules alone to predict every result of mutating a list during a loop. First separate the question of which elements the loop visits from the separate question of how a particular modification affects an ongoing iteration.
Predict Before Running
What do you think happens?
What values reach the loop body, in order, when the outer list contains a word, a nested list, and another word?
Reveal answer
The word, the entire nested list, then the final word
The loop is iterating over the outer list. The nested list is one element of that outer list, so it reaches the loop body as one whole element.
A
['B', 'C']
DBefore running a for loop, write down the outer list's elements in order. Mark each element as one item, even when that item is itself a list. Then write the value assigned to the loop variable on each iteration.
Hints
- Count elements in the outer list, not values inside a nested element.
- The loop variable receives an element value rather than an index.
- An empty outer list gives you no loop-body values to write down.
Common Prediction Errors
Common mistake Treating the loop variable as an index
What it looks likeA loop variable receives red, not the numeric position of the item.
Why it failsThe loop variable holds the actual element value on each iteration.
Do this insteadUse the element value directly. If an index is needed, use the range(len(list)) approach identified in the source material.
Common mistake Expecting the loop body to run once for an empty list
What it looks likeAssuming an empty list provides a blank item.
Why it failsAn empty list has no element to assign to the loop variable.
Do this insteadPredict zero loop-body executions.
Common mistake Flattening a nested list mentally
What it looks likePredicting separate iterations for B and C when the outer list contains [B, C] as one element.
Why it failsNested lists are treated as single elements during iteration over the outer list.
Do this insteadCount the nested list once at the outer level.
Common mistake Assuming the basic traversal rule completely explains mutation
What it looks likeUsing only the fact that a loop visits list elements to predict the result of adding or removing an element during iteration.
Why it failsThe provided material does not define the detailed effects of list modification during an ongoing iteration.
Do this insteadSeparate the established traversal facts from mutation-specific rules that must be learned separately.
Iteration Checklist
- 1A for loop is a natural way to traverse the elements of a list.
- 2The loop variable receives each element value, not its index.
- 3An empty list causes the loop body to execute zero times.
- 4A nested list is one element of its outer list during outer-list iteration.
- 5To predict output, list the outer elements in order and assign each one to the loop variable in turn.
Key Takeaways
- For loops visit list elements in order and provide each element to the loop body.
- The loop variable stores an element value rather than an index.
- An empty list produces no loop-body executions.
- A nested list counts as one element when iterating over its outer list.
- The provided material establishes traversal behavior but does not define the detailed effects of modifying a list during an ongoing iteration.