Concepts / Iterating Over Strings with for Loops

Iterating Over Strings with for Loops

A for loop executes a block of code once for each element in a list, with the loop variable taking on each element's value in sequence.

  • 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 Instruction, Many Characters

Suppose you want to display every character in a word. You could handle each character separately, but a for loop lets you write the processing instruction once and run it for every character. When Python traverses a string with a for loop, it automatically assigns one character at a time to a loop variable.

python
Output
b
a
n
a
n
a

What do you think happens?

Before reading the explanation, predict how many times print(char) runs and what char contains on the first and last iterations.

Reveal answer
Answer:

print(char) runs six times. char contains b on the first iteration and a on the last iteration.

The string banana has six characters. The loop visits them in order, assigning one character to char during each iteration.

Positions Become Iterations

The string banana contains six characters. Their positions correspond to the order in which the loop receives them: b first, then a, then n, then a, then n, then a. The loop variable receives the character itself rather than displaying the position number. You do not manually write an index, increment a counter, or check whether the end of the string has been reached.

0b1a2n3a4n5anextnextnextnextnext
How does each position in banana correspond to the character received by the loop?
Best practice

A for loop is simpler and more readable than manually traversing a string with a while loop and index tracking. The loop makes the intention clear: visit every character in order. It also avoids having to remember to increment an index or check whether the end of the string has been reached.

Following the Loop Variable

To trace a loop, record the loop variable's value at every iteration and then record what the loop body does with that value. In the example below, char is reassigned as control moves through fruit. It does not keep all the characters at once; it holds the current character for the current iteration.

Iteration 1char = b; output bIteration 2char = a; output aIteration 3char = n; output nIteration 4char = a; output aIteration 5char = n; output nIteration 6char = a; output anext characternext characternext characternext characternext character
What character does char contain at each iteration, and what output is produced?
Worked example

Adding a Message Around Each Character

Trace what happens when each character in the string code is printed with a label.

  1. 1
    First iteration

    char receives c. The loop body prints Character: c.

  2. 2
    Second iteration

    char receives o. The loop body prints Character: o.

  3. 3
    Third iteration

    char receives d. The loop body prints Character: d.

  4. 4
    Fourth iteration

    char receives e. The loop body prints Character: e.

  5. 5
    After the loop

    All four characters have been visited, so execution continues with the next unindented statement.

Result

The loop body runs four times, once for each character, in the order c, o, d, e.

python
Output
Character: c
Character: o
Character: d
Character: e
Finished

Inside and After the Loop

Indentation determines which statements belong to the loop body. A statement indented under the for statement runs once for every character. A statement at the original indentation level runs after the loop has processed all characters. This difference controls whether an action repeats or happens only once.

StartNext characterassign to charLoop bodyruns once per characterMore charactersAfter-loop statementruns onceEndyesno
Which statements run once per character, and which statement runs only after every character has been processed?
Before
word = "go"
for char in word:
    print(char)
    print("Finished")

Finished is indented, so it runs once for each character.

After
word = "go"
for char in word:
    print(char)
print("Finished")

Finished is not indented under the loop, so it runs after both characters have been processed.

Naming the Current Character

The loop variable name is arbitrary. In a string loop, names such as char or letter can indicate that the variable holds one character. A descriptive name makes the loop self-documenting. A short name may work, but it gives the reader less information about the value being processed.

Loop formValue received by the loop variableReadability
for char in fruitOne character from fruitDescriptive
for letter in fruitOne character from fruitDescriptive
for f in fruitOne character from fruitLess clear

Different loop variable names can work identically, but descriptive names communicate intent more clearly.

python

Mistakes During Traversal

  • Common mistake

    Forgetting to indent the loop body.

    What it looks like
    for char in word:
    print(char)
    Why it fails

    The statement intended to run for each character is not indented under the for statement.

    Do this instead

    Indent the loop body so Python can identify it as part of the loop.

  • Common mistake

    Indenting code that should run after the loop.

    What it looks like
    for char in word:
        print(char)
        print("Finished")
    Why it fails

    Finished is inside the loop, so it runs once per character rather than once after all characters.

    Do this instead

    Place the final print statement at the original indentation level.

  • Common mistake

    Using the wrong variable name inside the loop.

    What it looks like
    for char in word:
        print(letter)
    Why it fails

    The loop assigns characters to char, not letter.

    Do this instead

    Use the same loop variable name in the body, such as print(char).

  • Common mistake

    Expecting the loop variable to contain an index number.

    What it looks like
    for char in "banana":
        print(char)
    Why it fails

    A string loop gives the loop variable each character directly. It does not display the position number.

    Do this instead

    Treat char as the current character and trace the characters in their string order.

Edge case

Repeated characters are still visited separately. In banana, the loop receives a, n, and a at different iterations. The loop does not remove or skip a character merely because the same character appeared earlier.

Debugging

When the output differs from your expectation, write the string's characters in order and place one character beside each iteration. Then check three points: whether every character appears in the expected order, whether the loop variable name matches the name used in the body, and whether each statement has the intended indentation.

Practice the Trace

EASY

Write a for loop that traverses the string "lamp". For each character, print the text "Current:" followed by the character. Then print "All done" only after the loop completes.

Hints
  • Use a descriptive loop variable such as char.
  • Place the repeated print statement inside the loop.
  • Place the final print statement at the original indentation level.
MEDIUM

Trace this loop without running it. Write the value of letter and the output produced on each iteration: word = "tree"; for letter in word: print(letter). Then explain why the repeated e characters produce two separate iterations.

Hints
  • List the characters from left to right.
  • The loop variable receives one character during each iteration.
  • Repeated characters remain separate positions in the traversal.

A reliable trace follows the same pattern every time: identify the next character, assign it mentally to the loop variable, execute the indented body, and then move to the next character. After the final character, stop repeating the indented body and continue with the unindented code.

Key Takeaways

  1. 1
    A for loop over a string assigns each character to its loop variable in sequence.
  2. 2
    The loop body runs once for every character, while unindented code runs after the loop completes.
  3. 3
    Tracing the loop variable step by step helps you predict output and locate unexpected behavior.
  4. 4
    The loop variable name can be chosen freely, but a descriptive name makes the code easier to understand.
  5. 5
    A for loop handles the traversal automatically, so manual index tracking is not required.

At a glance

  • A string for loop visits characters from first to last.
  • The loop variable holds the current character and changes on each iteration.
  • Indentation separates repeated loop-body work from work that happens after the loop.
  • Tracing each character and output is an effective way to predict results and debug loops.
  • Descriptive loop variable names improve readability.

Related concepts

More concepts starting with I