Concepts / Nested Data Structures and Multi-Level Iteration

Nested Data Structures and Multi-Level 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 direct way to visit each item in turn. The loop variable receives the actual element value during each iteration. It does not automatically receive the element's index.

python
Output
red
green
blue
[red, green, blue]outer listredcolorgreencolorbluecoloriteration 1iteration 2iteration 3
What element does the loop variable contain as the loop moves from the first list element to the last?

Reading the Outer List

A list traversal visits the list's elements in order. On the first iteration, the loop variable contains the first element; on the next iteration, it contains the next element; and so on until every element has been visited. You usually do not need to access each element manually by index. If an index is specifically required, the source notes that you can use range(len(list)) instead.

Worked example

Tracing Three Iterations

Determine the values assigned to item while traversing ["A", "B", "C"].

  1. 1
    First iteration

    item contains the first list element, "A".

  2. 2
    Second iteration

    item contains the second list element, "B".

  3. 3
    Third iteration

    item contains the third list element, "C".

Result

The loop processes "A", then "B", then "C".

Nested Lists as Outer Elements

A nested list is still one element from the point of view of the outer list. If an outer list contains values and another list, the outer loop does not automatically visit the individual values inside that nested list. Instead, one iteration assigns the entire inner list to the loop variable.

Before
groups = [["A", "B"], ["C", "D"]]
for group in groups:
    print(group)

The outer loop receives ["A", "B"] once and ["C", "D"] once.

After
groups = [["A", "B"], ["C", "D"]]
for group in groups:
    for item in group:
        print(item)

The second loop visits A, B, C, and D inside the two inner lists.

[A, B]one outer elementAinner iterationBinner iterationsecond loopsecond loop
Does the outer loop process each value inside a nested list individually, or does it receive the entire inner list as one element?
outer list[[A, B], [C, D]][A, B]outer variableAinner variable[C, D]outer variableBinner variableCinner variableDinner variableouter iteration 1outer iteration 2inner iterationinner iterationinner iterationinner iteration
When an outer loop reaches an inner list, what does the second loop process?

Empty List Behavior

An empty list contains no elements to visit. Therefore, a for loop over an empty list performs zero iterations: the loop body never executes. This is expected behavior, not an error.

empty list[]element availablenoloop endszero iterationsbeginno element
What happens to the loop body when the list contains no elements?
python
Output
finished

Predicting the Output

What do you think happens?

What values are printed, and in what order, when the loop visits ["first", "second", "third"]?

  • first, second, third

  • 0, 1, 2

  • third, second, first

Reveal answer
Answer:

first, second, third

The loop variable receives each actual element value in list order. It does not automatically receive the indexes.

firstoutput 1secondoutput 2thirdoutput 3next iterationnext iteration
Given a list and a for loop, what values are produced and in what order before the code is executed?
EASY

Predict the output before running this loop: values = ["north", "south"]. The loop prints each value as it visits the list.

Hints
  • The loop variable receives actual values rather than indexes.
  • Follow the list from its first element to its last element.

Mistakes with Loop Levels

  • Common mistake

    Assuming the loop variable contains an index

    What it looks like

    For a list containing 10, 20, and 30, expecting the loop variable to be 0, 1, and 2.

    Why it fails

    A standard for loop over a list assigns the actual element value to the loop variable.

    Do this instead

    Reason about the values 10, 20, and 30. Use range(len(list)) when the index is needed.

  • Common mistake

    Assuming an outer loop automatically reaches inner values

    What it looks like

    Expecting one loop over [["A", "B"], ["C", "D"]] to process A, B, C, and D individually.

    Why it fails

    Each inner list is one element of the outer list.

    Do this instead

    Use a second loop when the individual elements inside each nested list must be visited.

  • Common mistake

    Treating zero iterations as an error

    What it looks like

    Expecting the loop body to run once when the list is [].

    Why it fails

    An empty list has no elements, so there is nothing for the loop to assign to its variable.

    Do this instead

    Expect the loop body to execute zero times and continue with the code after the loop.

Best practice

Before running a loop, write down the outer list's elements in order. For a nested list, keep each inner list grouped as one outer element. Only split that inner group into individual values when a second loop processes it.

Practice Traversal

MEDIUM

For each case, predict how many times the loop body executes and what the loop variable receives: a list containing four ordinary values; an empty list; and a list containing two nested lists. Then explain what additional loop is needed to reach values inside the nested lists.

Hints
  • Count the elements of the list being directly traversed.
  • An empty list has no element for the loop variable.
  • Treat each nested list as one element until a second loop traverses it.

Essential Takeaways

  1. 1
    A for loop visits list elements in order.
  2. 2
    The loop variable contains the actual element value, not the index.
  3. 3
    An empty list causes zero loop-body executions and is not an error.
  4. 4
    A nested list is one element of its outer list during outer-loop iteration.
  5. 5
    A second loop is needed to visit the individual elements inside each nested list.

At a glance

  • A for loop traverses a list by assigning each actual element to its loop variable in order.
  • The loop variable is a value, not an index.
  • An empty list produces zero iterations.
  • A nested list remains one outer element until another loop traverses its contents.
  • Predict output by tracing the elements at the current loop level.

Related concepts

More concepts starting with N