Concepts / Nested Loops and Complex Iterations

Nested Loops and Complex Iterations

A for loop traverses a string by automatically assigning each character to a loop variable, one character per 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…

A Character at a Time

A for loop can visit every character in a string without requiring you to manage index numbers yourself. During each iteration, Python assigns the next character to the loop variable, runs the loop body, and then continues to the next character. The loop stops after all characters have been visited.

Mapping Positions to Characters

Consider the string banana. It contains six characters. A string index identifies a position, while a for loop assigns the character at that position to the loop variable. The loop does not display the index; it exposes the character itself. The repeated a and n characters are visited because they occur at separate positions in the string.

Index 0bcharone character per iterationIndex 1aIndex 2nIndex 3aIndex 4nIndex 5aiteration 1iteration 2iteration 3iteration 4iteration 5iteration 6
Which character does the loop variable contain at each iteration, and how does each iteration correspond to a string index?

The diagram shows the relationship between positions and loop values. At the first position, char receives b. At the next position, it is reassigned to a, and this continues in order until the final a. The variable is reused, but its value changes at every iteration.

Tracing Every Iteration

What do you think happens?

If a loop visits the string banana and prints the loop variable once per iteration, what characters will it print in order?

  • banana

  • banna

  • 0 1 2 3 4 5

  • Only the first character

Reveal answer
Answer:

banana

The loop visits all six characters in order: b, a, n, a, n, and a. It prints characters rather than their index numbers.

Iteration 1char = bIteration 2char = aIteration 3char = nIteration 4char = aIteration 5char = nIteration 6char = aLoop endsall characters visitednext characternext characternext characternext characternext characterno characters remain
What happens next as the for loop moves from the first character to the last character?

A useful trace records two things for every iteration: the current value of the loop variable and the action performed by the loop body. After the body runs for b, control returns to the loop so the variable can receive a. The same process repeats for n, a, n, and a. Once the final character has been processed, there is no next character, so the loop stops automatically.

Writing the Loop

In a string-traversal loop, the variable after for holds the current character, the value after in is the string being traversed, and the indented body contains the processing performed for each character. The keyword in tells Python to iterate through the string's elements.

python
Output
b
a
n
a
n
a
PartRole
charThe loop variable that receives one character at a time
inThe keyword that introduces the values being traversed
fruitThe string being traversed
print(char)The loop body that runs for each character

Parts of a string-traversal for loop

Following Control Flow

Start loopbegin string traversalGet characterassign next value to charProcess charrun the loop bodyMore charactersanother value remainsLoop endsall characters visitedbegincharacter assignedbody completesyesno
How does control flow return to the loop after processing one character, and when does the loop stop?

The loop body is not the whole loop. After the body processes the current character, control returns to the iteration mechanism. Python assigns the next character to the loop variable and runs the body again. This automatic progression is why you do not need to increment an index or manually test whether the end of the string has been reached.

Best practice

Choose a loop variable name that communicates its role. Names such as char or letter make it clear that the variable represents one character, although Python allows you to choose another name.

Diagnosing Unexpected Traversal

When the output is not what you expected, trace the loop one iteration at a time. Write down the character assigned to the loop variable and the action performed by the body. Compare that trace with the characters in the original string in order. The first difference identifies where the loop's observed behavior diverges from your expectation.

  • Common mistake

    Expecting the loop variable to contain an index number.

    What it looks like

    A trace records char as 0, 1, 2, 3, 4, and 5 instead of b, a, n, a, n, and a.

    Why it fails

    A for loop over a string assigns each character directly to the loop variable.

    Do this instead

    Trace the character value held by the variable at each iteration.

  • Common mistake

    Assuming repeated characters were skipped.

    What it looks like

    The two occurrences of a in banana are treated as one visit.

    Why it fails

    The loop visits positions in order, so repeated characters at different positions are visited separately.

    Do this instead

    Record each iteration in sequence, even when the character value is the same as one seen earlier.

  • Common mistake

    Adding manual stopping or index management to a simple traversal.

    What it looks like

    The loop includes extra logic to increment an index or check whether the string has ended.

    Why it fails

    The for loop automatically continues until all characters have been visited.

    Do this instead

    Let the for loop handle progression and termination when your task is to process every character.

  • Common mistake

    Looking only at the loop header and ignoring the indented body.

    What it looks like

    The character sequence is traced correctly, but the expected result does not match what the body actually does.

    Why it fails

    The body runs once for every character and determines the processing performed at each step.

    Do this instead

    Record both the current character and the body's action during every iteration.

Choosing the Clearer Approach

For loop over a stringManual index-based traversal
The loop variable receives each character directly.The programmer tracks index positions manually.
Python handles progression through the string.The programmer must remember to advance the index.
Python handles stopping after all characters are visited.The programmer must check whether the end has been reached.
The intent to visit every character is immediately visible.Index arithmetic can make the intent less direct.

Why a for loop is generally simpler for visiting every character

A while loop with manual index tracking can also traverse a string, but a for loop is simpler and less error-prone for this purpose. It avoids manual index increments and end checks. It also communicates the intent clearly: visit each character and run the body once for each one.

Practice the Trace

EASY

Suppose a for loop traverses the string banana. Create a six-row trace. For each row, record the iteration number, the character held by the loop variable, and the action performed by a loop body that prints the character. Then explain why the loop stops after the sixth row.

Hints
  • The string contains six characters.
  • Begin with b and preserve the original order.
  • The loop stops when there are no characters left to visit.
EASY

Write a for loop that traverses a string stored in a variable named fruit and processes each character by printing it. Before running the loop, predict the sequence of characters that will be processed when fruit contains banana.

Hints
  • Use a loop variable such as char or letter.
  • Place the string variable after in.
  • Put the processing statement inside the indented loop body.

Key Takeaways

  1. 1
    A for loop over a string assigns one character to its loop variable per iteration.
  2. 2
    The loop visits characters in their string order and continues until all characters have been visited.
  3. 3
    The loop variable contains the character, not the index number, although each iteration corresponds to an index position.
  4. 4
    Tracing the variable and loop body step by step helps predict output and locate unexpected behavior.
  5. 5
    For loops are usually clearer and less error-prone than manual index-based traversal when processing every character.

At a glance

  • A for loop automatically assigns each character in a string to a loop variable.
  • For the string banana, the loop receives b, a, n, a, n, and a in that order.
  • Tracing each iteration connects the loop variable to the corresponding string position.
  • The loop handles progression and termination automatically.
  • Manual tracing is a practical way to debug unexpected string-traversal behavior.

Related concepts

More concepts starting with N