For Loops and Range
for i in range(1, 5): print i else : print 'The for loop is over'
What Does a For Loop Do?
A for loop lets you repeat a block of code multiple times, once for each item in a sequence. Instead of writing the same code over and over, you write it once and let the loop handle the repetition. The key insight is that the loop variable (often called i) takes on a different value each time through the loop, and you can use that value inside your code block.
The most common way to create a sequence of numbers to loop over is the range() function. When you write for i in range(1, 5), Python creates a sequence of numbers and your loop visits each one in order, assigning it to i and running your code block.
How Range Generates Numbers
The range() function is a built-in Python tool that generates a sequence of numbers. It does not create all the numbers at once and store them in memory. Instead, it generates one number at a time, on demand, as your for loop requests each one. This is efficient, especially when you need a very long sequence.
To see all the numbers range() would produce, you can convert it to a list using list(range()). For example, list(range(1, 5)) shows you [1, 2, 3, 4]. But inside a for loop, you do not need to do this conversion; the loop automatically gets each number one at a time.
range(start, stop) generates integers beginning at start and ending just before stop. The start value is included; the stop value is excluded.
Stepping Through a For Loop
Let us trace through a concrete example to see exactly what happens as a for loop runs. Understanding this step-by-step execution is the key to mastering loops.
Tracing for i in range(1, 5): print(i)
What does this code print, and what is the value of i at each step?
Iteration 1: Python starts the loop and assigns i = 1 (the first value from range(1, 5)). The code block print(i) runs, printing 1.
Iteration 2: Python moves to the next value in the sequence and assigns i = 2. The code block runs again, printing 2.
Iteration 3: Python assigns i = 3 and runs the code block, printing 3.
Iteration 4: Python assigns i = 4 and runs the code block, printing 4.
Loop ends: range(1, 5) has no more values to produce (5 is excluded). The loop exits and any code after the loop runs next.
The output is: 1 2 3 4 (each on its own line)
Controlling Range with Start, Stop, and Step
The range() function accepts up to three parameters: start, stop, and step. Understanding how each one works gives you precise control over which numbers your loop visits.
range(stop) generates integers from 0 up to (but not including) stop. This is the simplest form.
range(start, stop) generates integers from start up to (but not including) stop, incrementing by 1 each time.
range(start, stop, step) generates integers from start up to (but not including) stop, incrementing by step each time. The step can be negative to count backwards.
| Code | What it produces | Explanation |
|---|---|---|
| range(5) | [0, 1, 2, 3, 4] | Starts at 0 (default), stops before 5, step is 1 (default) |
| range(2, 6) | [2, 3, 4, 5] | Starts at 2, stops before 6, step is 1 |
| range(0, 10, 2) | [0, 2, 4, 6, 8] | Starts at 0, stops before 10, increments by 2 each time |
| range(5, 0, -1) | [5, 4, 3, 2, 1] | Starts at 5, stops before 0, decrements by 1 each time (negative step) |
The For...Else Clause
Python allows you to attach an else clause to a for loop. The code in the else block runs after the loop completes normally (that is, when the loop finishes all its iterations without hitting a break statement). This is useful when you want to execute code only if the loop ran to completion.
1
2
3
4
The for loop is overIn this example, the loop runs through all four iterations (1, 2, 3, 4), and after the last iteration completes, the else block executes and prints 'The for loop is over'. If the loop had encountered a break statement, the else block would have been skipped.
For Loops Work with Any Sequence
While range() is the most common way to generate a sequence of numbers, the for loop works with any sequence. You can loop over lists, strings, tuples, and other sequence types. The loop variable takes on each element of the sequence, one at a time, and you can use it in your code block.
This flexibility is one of the most powerful features of for loops in Python. Whether you are iterating over numbers from range(), items in a list, or characters in a string, the same loop structure applies. We will explore this idea in detail in later chapters when we cover data structures like lists and strings.
Common Mistakes with For Loops and Range
Forgetting that range(stop) excludes the stop value
The stop parameter is exclusive. range(5) means 'up to but not including 5'.
Fix:
If you want to include 5, use range(6) instead.Confusing range(start, stop) with range(stop, start)
range(5, 1) means 'start at 5, go up to but not including 1'. Since 5 is already past 1, there are no values to generate.
Fix:
Use range(5, 1, -1) to count backwards from 5 to 2.Assuming the loop variable i exists before the loop starts
The loop variable is created by the for statement itself, on the first iteration.
Fix:
Only use the loop variable inside the loop body or after the loop has run at least once.Using list(range()) inside a loop when you do not need to
This wastes memory. range() generates values on demand, which is more efficient.
Fix:
Use for i in range(1000000) directly; the loop will request each value as needed.
Practice: Writing Your Own For Loops
Write a for loop that prints the numbers 10, 20, 30, 40, 50. Use range() with appropriate start, stop, and step parameters.
Hints
- You want to start at 10 and go up to (but not including) 60.
- The step should be 10 to increment by 10 each time.
- The code should be: for i in range(10, 60, 10): print(i)
Write a for loop that counts backwards from 5 to 1 and prints each number. Then add an else clause that prints 'Countdown complete!' after the loop finishes.
Hints
- Use a negative step to count backwards.
- range(5, 0, -1) will give you 5, 4, 3, 2, 1.
- The else block should be at the same indentation level as the for statement.
Predict: What does this code print? for i in range(3): print(i * 2)
Hints
- range(3) produces 0, 1, 2.
- For each value of i, you print i * 2.
Key Takeaways
- A for loop repeats a block of code once for each item in a sequence, with the loop variable taking on each value in turn.
- range() generates a sequence of numbers on demand (one at a time), not all at once. Use list(range()) only if you need to see all values immediately.
- range(start, stop) includes start but excludes stop. range(start, stop, step) lets you control the increment or decrement.
- The loop variable persists after the loop ends and retains the value of the last iteration.
- A for...else clause runs only if the loop completes normally (without hitting a break statement).
- For loops work with any sequence type, not just range(). This makes them powerful for iterating over lists, strings, and other data structures.
Key Takeaways
- For loops repeat a code block for each item in a sequence, with the loop variable changing on each iteration.
- range(start, stop, step) generates numbers efficiently on demand; the stop value is always excluded.
- Trace through loops step-by-step to understand how the loop variable changes and when the code block runs.
- The for...else clause executes only when the loop completes normally, not when a break statement exits early.
- For loops work with any sequence type, making them a fundamental tool for iteration in Python.