Concepts / Modifying Lists During Iteration

Modifying Lists During Iteration

For loops are the most common and natural way to iterate through list elements, using identical syntax to string iteration.

  • Programming
Interactive lab

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

  1. The for statement asks the object for an iterator, then calls next() on it once per pass.
  2. 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.
  3. 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).
  4. 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.
  5. 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.
  6. 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.

Educational simulation

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.

Key point

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.

position 0reditemredposition 1greenitemgreenposition 2blueitembluefirst iterationsecond iterationthird iteration
How does the loop move from one list position to the next, and which element is assigned to the loop variable at each step?
Definition

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.

python
Output
red
green
blue

The 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.

outer listfirst item, inner list,third itemfirst iteminner listtwo valuesloop variableinner listthird itemcontainscontainscontainsone outer iteration
When a for loop iterates over an outer list, does it visit the inner list's individual values or treat the entire inner list as one element?

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.

empty listno elementsfind next elementnone availableloop endsbody runs zero timesbegin iterationno element
What path does control flow take when a for loop receives an empty list, and why does the loop body run zero times?
python
Output
No output

What 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.

listbeing traversedaddmodificationoutcomenot specified hereremovemodificationchangemodificationduring iterationduring iterationduring iterationrequires additional rulesrequires additional rulesrequires additional rules
What happens to the list and the next iteration when an element is added, removed, or changed while the for loop is running? The provided material defines the traversal model but does not define those modification outcomes.

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?

  • The word, each value inside the nested list, then the final word

  • The word, the entire nested list, then the final word

  • Only the values inside the nested list

  • No values, because nested lists cannot be iterated over

Reveal answer
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.

python
Output
A
['B', 'C']
D
EASY

Before 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 like

    A loop variable receives red, not the numeric position of the item.

    Why it fails

    The loop variable holds the actual element value on each iteration.

    Do this instead

    Use 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 like

    Assuming an empty list provides a blank item.

    Why it fails

    An empty list has no element to assign to the loop variable.

    Do this instead

    Predict zero loop-body executions.

  • Common mistake

    Flattening a nested list mentally

    What it looks like

    Predicting separate iterations for B and C when the outer list contains [B, C] as one element.

    Why it fails

    Nested lists are treated as single elements during iteration over the outer list.

    Do this instead

    Count the nested list once at the outer level.

  • Common mistake

    Assuming the basic traversal rule completely explains mutation

    What it looks like

    Using only the fact that a loop visits list elements to predict the result of adding or removing an element during iteration.

    Why it fails

    The provided material does not define the detailed effects of list modification during an ongoing iteration.

    Do this instead

    Separate the established traversal facts from mutation-specific rules that must be learned separately.

Iteration Checklist

listordered elementsfirst elementloop variablesecond elementloop variablenext elementcontinues in orderloop endsafter elements are visitedfirst iterationnext iterationcontinueno more elements
In what order does each list element reach the loop body, and what output is produced at each iteration before the loop ends?
  1. 1
    A for loop is a natural way to traverse the elements of a list.
  2. 2
    The loop variable receives each element value, not its index.
  3. 3
    An empty list causes the loop body to execute zero times.
  4. 4
    A nested list is one element of its outer list during outer-list iteration.
  5. 5
    To 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.

Related concepts

More concepts starting with M