Concepts / Understanding List Indices

Understanding List Indices

Index-based iteration combines range() and len() to generate indices, enabling you to read and modify list elements.

  • Programming

A List That Changes

Suppose a list contains numbers that must all be doubled. The important question is not only which values are in the list, but also which position each value occupies. Index-based iteration gives the loop an index for each position. The loop can then read the old value at that position and assign a new value back to the same position.

What do you think happens?

A list starts as [3, 5, 7]. If a loop doubles the value at each index, what will the final list be?

  • [3, 5, 7]

  • [6, 10, 14]

  • [6, 5, 7]

  • [3, 10, 14]

Reveal answer
Answer:

[6, 10, 14]

Each iteration reads the value at the current index, doubles it, and writes the result back to that same position. Tracing the positions in order shows every element changing once.

Following Positions

index 0position 03list valueindex 1position 15list valueindex 2position 27list valuerefers torefers torefers to
Which list element does each index refer to?

An index identifies a position in the list. In the illustration, index 0 is paired with 3, index 1 with 5, and index 2 with 7. When a loop variable i holds one of these indices, numbers[i] selects the value at that position.

Generating Valid Indices

The combination range(len(numbers)) produces the sequence of indices used to visit the elements of numbers. len(numbers) supplies the list's length, and range() uses that length to generate the positions for the loop. The loop variable receives one generated index at a time.

len(numbers)3range(3)generated indices0first index1next index2next indexprovides lengthfirstthenthen
What indices does range(len(numbers)) produce, and how do those indices move through the list?
python

The expression numbers[i] appears on both sides of the assignment. On the right, it reads the old value at index i. Multiplication creates the replacement value. On the left, numbers[i] identifies the position where that replacement is written.

Reading and Replacing

Worked example

Doubling Every Element

Trace the loop for numbers = [3, 5, 7] and determine the final list.

  1. 1
    Index 0

    The old value at index 0 is 3. The assignment calculates 3 * 2 and writes 6 back to index 0. The list becomes [6, 5, 7].

  2. 2
    Index 1

    The old value at index 1 is 5. The assignment calculates 5 * 2 and writes 10 back to index 1. The list becomes [6, 10, 7].

  3. 3
    Index 2

    The old value at index 2 is 7. The assignment calculates 7 * 2 and writes 14 back to index 2. The list becomes [6, 10, 14].

Result

The final list is [6, 10, 14].

numbers[1]55 * 2new valuenumbers[1]10readwrite
How does the loop read the old value at an index and replace it with a new value?

Tracing the Final State

Tracing means recording the list after each iteration instead of jumping directly to the answer. At the beginning, the list is [3, 5, 7]. After index 0, it is [6, 5, 7]. After index 1, it is [6, 10, 7]. After index 2, it is [6, 10, 14]. This sequence shows exactly which element changed at each step.

[3, 5, 7]before loop[6, 5, 7]after index 0[6, 10, 7]after index 1[6, 10, 14]after index 2index 0index 1index 2
What does the list look like after each iteration, and what is its final state?
Best practice

For a trace, write down three things at every iteration: the current index, the old value selected at that index, and the complete list after the assignment. This makes the final state a consequence of visible steps rather than a guess.

Choosing an Iteration Style

Iteration needSuitable approachReason
Only read each valueValue-based iterationThe value itself is sufficient.
Update elements in the listIndex-based iterationThe index identifies where the replacement is written.

Choose the loop style according to whether the position is needed.

Read valuesvalue-basedvalueenough informationUpdate elementsindex-basedindexneeded for positionusesuses
When do you need an index, and when is iterating directly over values sufficient?

Use value-based iteration when the task only requires reading the values. Use index-based iteration when the task requires updating list elements, because the index tells the assignment which position should receive the new value.

Common Tracing Mistakes

  • Common mistake

    Treating numbers[i] on the right side as the new value

    What it looks like
    numbers[i] = numbers[i] * 2
    Why it fails

    The right side is evaluated first, so numbers[i] initially supplies the old value at index i.

    Do this instead

    Read the statement as: select the old value, calculate the replacement, then write it back to the same position.

  • Common mistake

    Updating only the value in your written trace

    What it looks like

    After processing index 0, recording only 6 instead of [6, 5, 7]

    Why it fails

    The loop changes one list element at a time, but the complete list is needed to trace later iterations.

    Do this instead

    Record the whole list after every assignment.

  • Common mistake

    Choosing value-based iteration for an update task

    What it looks like

    Using a loop that reads each value when the task requires replacing list elements

    Why it fails

    The task needs the position where the replacement belongs.

    Do this instead

    Use range(len(numbers)) so the loop variable supplies an index for the assignment.

Practice the Trace

EASY

Trace this loop by writing the complete list after each index is processed, then state the final list: values = [2, 4, 6]; for i in range(len(values)): values[i] = values[i] * 2

Hints
  • List the indices generated by range(len(values)).
  • At each index, read the old value before calculating its replacement.
  • Change only the selected position in your written list.
Worked example

Practice Check

Complete the trace for values = [2, 4, 6] when every selected value is doubled.

  1. 1
    Index 0

    The old value is 2, so the list becomes [4, 4, 6].

  2. 2
    Index 1

    The old value is 4, so the list becomes [4, 8, 6].

  3. 3
    Index 2

    The old value is 6, so the list becomes [4, 8, 12].

Result

The final list is [4, 8, 12].

Key Takeaways

  1. 1
    range(len(list)) generates indices for iterating through a list by position.
  2. 2
    In list[i] = list[i] * 2, the right side reads the old value and the left side writes the new value to the same position.
  3. 3
    Index-based iteration is appropriate when list elements must be updated.
  4. 4
    Value-based iteration is sufficient when values only need to be read.
  5. 5
    Tracing the list after each iteration reveals the final state.

At a glance

  • Use range(len(list)) to obtain indices that move through the list.
  • An indexed assignment reads an old element value and writes a replacement to that element's position.
  • Choose index-based iteration for updates and value-based iteration for read-only work.
  • Trace the index, old value, and complete list state at every iteration to predict the result.

Related concepts

More concepts starting with U