Using range() and enumerate() for Index-Based Loops
A basic for loop over a list gives the loop variable the actual element value. In the example, the variable contains red, then blue, then green. It does not automatically contain 0, 1, and 2, which would be the positions of those elements.
From the List to the Loop
When a list contains several items, a common task is to do something with each item in turn. Python's for loop provides a natural way to visit the elements one by one. The syntax is similar to the syntax used when iterating through a string: the loop variable receives one element, the loop body runs, and then the loop moves to the next element.
Tracing Each Element
items = ["red", "blue", "green"]
for item in items:
print(item)- 1On the first iteration, item contains red, so red is printed.
- 2On the second iteration, item contains blue, so blue is printed.
- 3On the third iteration, item contains green, so green is printed.
- The list contains three elements.
- The loop variable item receives the first element, then the second, then the third.
- The print operation runs once for each element.
red
blue
greenWhat do you think happens?
Before reading the result, predict the output produced by this loop: values = [4, 8, 12]; for value in values: print(value)
Reveal answer
4, then 8, then 12
The loop variable contains the actual element value on each iteration. It does not contain the element's index.
A basic for loop over a list gives the loop variable the actual element value. In the example, the variable contains red, then blue, then green. It does not automatically contain 0, 1, and 2, which would be the positions of those elements.
When the Position Matters
Sometimes the element value is enough. In other situations, the position is also needed. The supplied material identifies range(len(list)) as the approach to use when the index is required. The length determines how many positions are available, and range supplies the position values for the loop. The element can then be accessed using that position.
0 red
1 blue
2 greenLists Inside Lists
A nested list is still one element of the outer list. If an outer list contains a smaller list, one iteration visits that inner list as a whole. The loop does not automatically visit every value inside the nested list as separate outer-loop iterations.
A
['B', 'C']The outer loop has two iterations in this example: one for A and one for the nested list. The values B and C are not separate iterations of the outer loop.
Empty Lists
An empty list contains no elements to visit. Therefore, a for loop over an empty list does not enter its body even once. This is normal behavior, not an error. Any operation placed inside the loop is skipped because there is no loop value to process.
finishedMistakes in Prediction
Common mistake Assuming the loop variable contains the index
What it looks likeFor a list containing red, blue, and green, expecting item to contain 0, then 1, then 2
Why it failsA normal for loop over a list assigns the actual element value to the loop variable.
Do this insteadUse the element directly when the value is needed. Use range(len(items)) when the position is needed.
Common mistake Expecting a nested list to be flattened automatically
What it looks likeExpecting an outer loop over ["A", ["B", "C"]] to visit A, B, and C separately
Why it failsThe nested list is one element of the outer list.
Do this insteadTreat the nested list as the value received during one outer-loop iteration.
Common mistake Treating an empty-list loop as an error
What it looks likeExpecting the loop body to run once even when the list is []
Why it failsThere are no elements available, so there are no iterations.
Do this insteadExpect the loop body to run zero times and produce no output from operations inside that body.
Predict the output before running this loop: values = ["north", ["east", "west"]]. The loop prints each value it receives. State how many iterations occur and what the loop variable contains during each iteration.
Hints
- Count the elements of the outer list.
- The inner list is one element of the outer list.
- The loop variable receives the actual element value.
A Reliable Tracing Method
- 1Write down the elements of the list in their existing order.
- 2For each element, record the value assigned to the loop variable.
- 3Run the loop body once for each recorded element.
- 4If the list is empty, record zero iterations and skip the body.
- 5If an element is itself a list, keep that inner list together as one outer-loop value.
- 6If the position is required, identify the index-based form using
range(len(list)).
Predicting a Mixed List
Determine the output and number of iterations for a loop over ["start", ["middle", "inside"], "end"].
- 1Identify the outer elements
The outer list has three elements: the string start, the nested list ["middle", "inside"], and the string end.
- 2Trace iteration one
The loop variable contains start.
- 3Trace iteration two
The loop variable contains the complete nested list ["middle", "inside"].
- 4Trace iteration three
The loop variable contains end.
There are three outer-loop iterations. The nested list is processed as one element during the second iteration.
Key Takeaways
- 1A for loop is a natural way to visit every element in a list.
- 2The loop variable contains the actual element value, not its index.
- 3Use
range(len(list))when index-based access is needed. - 4An empty list causes zero loop-body executions and is not an error.
- 5A nested list counts as one element of the outer list during iteration.
At a glance
- A list for loop visits elements in order, assigning one actual element value to the loop variable at a time.
- The loop variable is not an index in a basic list iteration.
- Use
range(len(list))when the element position is needed. - Nested lists are single elements of the outer list, and empty lists produce zero iterations.