Historical Context & Motivation
Imagine you need to print "Hello" one thousand times. Without a loop, you would have to write one thousand print statements — tedious, error-prone, and practically impossible to maintain. The for loop was invented precisely to solve this problem: it tells the computer to repeat a block of code a specific number of times, or once for each item in a collection. This concept of iteration — the controlled repetition of instructions — is one of the most fundamental ideas in all of computer science.
The need for repetition in computation goes back to the very dawn of programming. Early computers were programmed by physically rewiring circuits, and any repeating task required the operator to reset the machine manually. As programming languages evolved, designers realized that loops were essential to making computers truly powerful. Let's trace that evolution.
DO loop. This allowed programmers to specify a variable, a start value, and an end value — the ancestor of today's counted loops.for(init; condition; update) syntax. This pattern influenced dozens of languages including Java, JavaScript, and C++.for loop that iterates directly over collections. Instead of managing index variables manually, Python lets you loop over items naturally — a design philosophy centered on readability.for...of in 2015.So how exactly does Python's for loop work? How do you tell it to count from 0 to 99, or to process every name in a list? And how can you trace what happens during each pass through the loop? These are the questions we'll answer in this lesson.
Core Principles & Definitions
Before we write any code, let's establish the foundational vocabulary and ideas that make for loops work. Every for loop, regardless of what it iterates over, relies on the same core principles.
Iteration
Loop Variable
for i in range(3), the loop variable is i, and it becomes 0, then 1, then 2.Iterable
range() function all produce iterables. The loop pulls one element at a time from the iterable.Loop Body
for statement. Everything inside this block runs once per iteration. In Python, indentation (typically 4 spaces) defines the body — no curly braces needed.The range() Function
range(n) produces 0 through n−1. You can also specify a start, stop, and step: range(start, stop, step).The basic syntax of a Python for loop is straightforward: for variable in iterable: followed by an indented body. The keyword for signals the start, in connects the loop variable to the iterable, and the colon : marks the end of the header line. Python then automatically assigns the next value from the iterable to the variable and executes the body until all values are exhausted.
Visual Explanation — How a For Loop Flows
The diagram below shows the control flow of a for loop. Notice how the program checks whether more items remain in the iterable before each iteration. If items remain, the loop variable is updated and the body executes. When no items remain, execution continues with the code after the loop.
This flowchart applies to every for loop you'll ever write in Python, whether you're looping over a range() of numbers, a list of strings, or even the characters in a single word. The mechanism is always the same: pull the next item, run the body, check again.
How range() and Collection Iteration Work
The range() Function in Detail
The range() function generates a sequence of integers. It has three forms, each adding more control over the generated sequence. Understanding these forms is crucial because range() is the most common way to run a for loop a specific number of times.
range(5) produces 0, 1, 2, 3, 4.range(2, 6) produces 2, 3, 4, 5.range(0, 10, 2) produces 0, 2, 4, 6, 8. Example: range(10, 0, -2) produces 10, 8, 6, 4, 2.range(1, 11), not range(1, 10).Looping Over Collections
Python's for loop truly shines when iterating over collections like lists, strings, and tuples. Instead of using an index to access elements, Python hands you each element directly. For example, for name in ["Alice", "Bob", "Carol"]: assigns name the value "Alice" on the first iteration, "Bob" on the second, and "Carol" on the third. This is cleaner and less error-prone than managing an index counter yourself.
You can also loop over a string character by character. Writing for ch in "hello": gives you "h", then "e", then "l", and so on. Any object that is iterable — meaning it can produce items one at a time — works with Python's for loop.
Tracing Iterations Step by Step
One of the most important skills in programming is tracing — manually walking through your code line by line and recording the value of each variable at each step. Tracing a for loop means keeping track of the loop variable's value, the output produced, and any other variables that change inside the body. This skill helps you predict what your code will do before you even run it, and it is essential for debugging.
x and the computed expression x * 2 for each iteration. The output column shows what appears on screen after each pass.When you trace a loop, draw a table with columns for each variable and the output. Add a new row for each iteration. This practice builds your mental model of how the computer executes your code. On quizzes and exams, trace tables are often required, so getting comfortable with them now will pay off significantly.
total = total + x), add a column for that variable too. Track its value before and after each iteration to catch off-by-one errors.Worked Example — Summing a List
Let's work through a complete example that combines looping over a collection with an accumulator pattern. The goal is to compute the sum of all scores in a list.
scores = [85, 92, 78, 95, 88]
total = 0total.
for score in scores:
total = total + scorescore takes each value from the list.print("Total:", total)
This outputs: Total: 438total = 0), and each trip through the loop adds more snow to it. By the end, you've built up a big result from many small additions. This pattern works for summing, counting, building strings, and many other tasks.range() Loops vs. Collection Loops — When to Use Each
Now that you know both styles of for loop, a natural question arises: when should you use for i in range(n) versus for item in collection? The table below compares the two approaches to help you choose the right one for each situation.
| Feature | for i in range() | for item in collection |
|---|---|---|
| Best for | Repeating an action a specific number of times, or when you need the index | Processing each element in a list, string, or other collection |
| Loop variable holds | An integer (the current count or index) | The actual item from the collection (string, number, etc.) |
| Example | for i in range(5): print(i) | for name in names: print(name) |
| Pythonic? | Yes, when counting is the goal. Avoid using range(len(list)) just to get items. | Yes — this is the preferred Python style when you need each item directly. |
| Risk | Off-by-one errors if you forget stop is exclusive | Cannot easily access the index unless you use enumerate() |
range(). Avoid for i in range(len(my_list)) when for item in my_list does the job — simpler code has fewer bugs.Connection to Advanced Concepts
The for loop you've learned today is the gateway to many powerful programming techniques. As you advance, you'll encounter nested loops (loops inside loops), while loops that repeat based on a condition rather than a collection, and list comprehensions that let you build new lists in a single line. The table below previews how today's concepts connect to what's ahead.
| Today's Concept | Advanced Extension | What's Different |
|---|---|---|
for i in range(n) | Nested loops: for i in range(n): for j in range(m) | The inner loop runs completely for each iteration of the outer loop, creating n × m total iterations. |
for item in collection | List comprehensions: [x*2 for x in nums] | A compact one-line syntax to build a new list by transforming each item. Same logic, shorter code. |
| For loop (iterates over known items) | While loop (iterates while a condition is true) | While loops don't need a collection — they repeat as long as a Boolean condition remains True. Useful when you don't know how many iterations you need. |
| Tracing by hand | Using a debugger (e.g., Python's pdb or VS Code debugger) | Debuggers let you step through code line by line on screen, inspect variables, and set breakpoints — an automated version of tracing. |
Don't worry about mastering these advanced topics right now. The important thing is that every one of them builds on the same fundamentals you're learning today: iterating over data, updating variables inside a loop body, and tracing what happens at each step. If you can do these three things confidently, you have a strong foundation for everything that comes next.
Practice Problems
Test your understanding with these five problems. They start with basic recall and build up to critical thinking. Try to answer each one on paper before reading the solution.
for color in ["red", "green", "blue"]:, how many iterations will occur? What is the value of color during the second iteration?range(2, 10, 3) produce? List all the values.count:
count = 0
for letter in "banana":
if letter == "a":
count = count + 1
print(count)grades = [88, 76, 95, 63, 91, 84]. Write a for loop that prints only the grades that are 80 or above. Then, write a second loop that calculates the average of all grades.words = ["cat", "dog", "bird"]
for w in words:
print(len(w))
Snippet B:
words = ["cat", "dog", "bird"]
for i in range(len(words)):
print(len(words[i]))Lesson Summary
A Python for loop repeats a block of code once for each item in an iterable. You can loop over a range() of integers when you need to repeat an action a specific number of times, or loop directly over a collection (like a list or string) to process each element. The loop variable automatically takes on the next value from the iterable at the start of each iteration.
The accumulator pattern (initializing a variable before the loop and updating it inside) lets you compute sums, counts, and other aggregated results. Tracing — building a table that tracks variable values across each iteration — is an essential debugging and exam skill. Remember: range(stop) starts at 0 and the stop value is always exclusive. When you only need items (not indices), loop over the collection directly — it's the Pythonic way.