The range() Function
Index-based iteration combines range() and len() to generate indices, enabling you to read and modify list elements.
A List That Changes While You Loop
Suppose a list contains numbers that must all be doubled. The loop needs two pieces of information at every step: the position of the current element and the value stored there. Combining range() with len() generates the positions, so the loop can read an old value and write a new value back into the same list position.
What do you think happens?
A list contains [3, 5, 7]. If an index-based loop doubles the value at each position, what final list should you expect?
Reveal answer
Answer: [6, 10, 14]
Each iteration reads the old value at the current index, multiplies it by 2, and assigns the result back to that same position.
Following the Generated Indices
In the pattern range(len(numbers)), len(numbers) represents the size of the list, and range() provides the indices used by the loop. The loop variable receives one index at a time. That index can then select the corresponding element with numbers[i].
Reading and Replacing an Element
The assignment numbers[i] = numbers[i] * 2 performs both parts of the update. The right side, numbers[i] * 2, reads the old value at index i and calculates a new value. The left side, numbers[i] =, writes that new value back to the same position. Because the assignment uses the index, the original list element is replaced rather than merely copied into a temporary loop variable.
Tracing Every List State
Doubling Each Element
Trace the loop for numbers = [3, 5, 7] and determine the final list.
Starting state: The list begins as [3, 5, 7].
First iteration: The loop uses the first generated index. It reads the value 3, doubles it, and writes 6 back to that position. The list becomes [6, 5, 7].
Second iteration: The loop uses the next index. It reads 5, doubles it, and writes 10 back to that position. The list becomes [6, 10, 7].
Third iteration: The loop uses the remaining index. It reads 7, doubles it, and writes 14 back to that position. The list becomes [6, 10, 14].
The final list is [6, 10, 14].
[6, 10, 14]Choosing the Loop Style
| Iteration style | Use it when | What the loop has |
|---|---|---|
| Index-based | You need to update elements | An index that can select and assign to a list position |
| Value-based | You only need to read values | The current value without needing its position |
Start by asking what the loop must accomplish. If it only reads each value, value-based iteration is sufficient. If it must update an element in the list, use index-based iteration with range() and len() so the assignment can target the element's position.
Mistakes During Index Tracing
Forgetting that the right side is evaluated before the assignment changes the list.
The statement first reads the old value at index i, calculates the new value, and then writes the result back.
Fix:
Trace each iteration as read old value, calculate new value, assign new value.Choosing value-based iteration when the list element must be updated.
Updating the list requires the position used on the left side of the assignment.
Fix:
Use range(len(list)) when the loop needs to update elements.Predicting the final list without recording intermediate states.
The loop changes one element at a time, and each change affects the list state used in the next step of the trace.
Fix:
Write the list after every iteration before deciding the final state.
Trace Before You Run
A list starts as [4, 1, 6]. An index-based loop reads the value at each index, adds 3 to it, and assigns the result back to the same position. Write the list after each iteration and then give the final list.
Hints
- Use one index at a time.
- For each index, read the old value before calculating the replacement.
- Keep the values that have not yet been visited unchanged.
Practice Check
Trace the generated example for [4, 1, 6] when 3 is added to each element.
First update: The first value becomes 7, giving [7, 1, 6].
Second update: The second value becomes 4, giving [7, 4, 6].
Third update: The third value becomes 9, giving [7, 4, 9].
The final list is [7, 4, 9].
Key Takeaways
- range() and len() can be combined to generate indices for iterating through a list.
- numbers[i] = numbers[i] * 2 reads the old value at index i and writes the doubled value back to that position.
- Use index-based iteration when list elements must be updated.
- Use value-based iteration when values only need to be read.
- Tracing the list after each iteration makes the final state predictable.
Key Takeaways
- range(len(list)) supplies indices that let a loop work through list positions.
- An indexed assignment can read an old value, transform it, and replace the element in one statement.
- Index-based iteration is appropriate for updates; value-based iteration is sufficient for reading.
- A step-by-step trace records each intermediate list state and reveals the final result.