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
[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.
- 1Starting state
The list begins as [3, 5, 7].
- 2First 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].
- 3Second 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].
- 4Third 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 |
Choose the style according to whether the list itself must be updated.
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
Common mistake Forgetting that the right side is evaluated before the assignment changes the list.
What it looks likenumbers[i] = numbers[i] * 2Why it failsThe statement first reads the old value at index i, calculates the new value, and then writes the result back.
Do this insteadTrace each iteration as read old value, calculate new value, assign new value.
Common mistake Choosing value-based iteration when the list element must be updated.
What it looks likeA loop that only receives each value cannot provide the indexed assignment described by numbers[i] = numbers[i] * 2.
Why it failsUpdating the list requires the position used on the left side of the assignment.
Do this insteadUse range(len(list)) when the loop needs to update elements.
Common mistake Predicting the final list without recording intermediate states.
What it looks likeJumping directly from [3, 5, 7] to the answer.
Why it failsThe loop changes one element at a time, and each change affects the list state used in the next step of the trace.
Do this insteadWrite 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.
- 1First update
The first value becomes 7, giving [7, 1, 6].
- 2Second update
The second value becomes 4, giving [7, 4, 6].
- 3Third update
The third value becomes 9, giving [7, 4, 9].
The final list is [7, 4, 9].
Key Takeaways
- 1
range()andlen()can be combined to generate indices for iterating through a list. - 2numbers[i] = numbers[i] * 2 reads the old value at index i and writes the doubled value back to that position.
- 3Use index-based iteration when list elements must be updated.
- 4Use value-based iteration when values only need to be read.
- 5Tracing the list after each iteration makes the final state predictable.
At a glance
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.