Concepts / Mutating Lists: append(), remove(), and Assignment

Mutating Lists: append(), remove(), and Assignment

List traversal comes in two main forms: simple for loops for reading elements, and index-based loops using range(len()) for updating elements.

  • Programming

Two Ways to Traverse

List traversal means moving through the elements of a list. The two patterns in this lesson have different purposes. A simple for loop visits each element's value directly, which is useful when you only need to inspect or display the elements. An index-based loop uses range(len(list)) to produce positions, allowing the loop to read an element and update the value stored at that position.

Choose direct traversal when the list only needs to be read. Choose index-based traversal when the loop must update elements in the list.

visitsselectsfor item in listreads each valueelement valueinspect or displayrange(len(list))produces positionslist[index]read or update
What is the difference between a loop that reads values directly and a loop that uses positions to update list elements?

Direct Reading Traversal

In a simple for loop, the loop variable represents the current element's value. The loop moves from one element to the next and gives the body of the loop the value to inspect or display. This pattern does not provide a list position for an update. It is therefore the appropriate pattern when the task is reading rather than changing the list.

Reading Each Value

Consider a list containing the values 4, 7, and 9. Trace a direct reading traversal.

First visit: The loop receives the first element's value, 4.

Second visit: The loop advances and receives the next element's value, 7.

Third visit: The loop advances again and receives the final element's value, 9.

The traversal reads 4, then 7, then 9. No list position is supplied for an in-place update.

Index-Based Updating

The pattern for i in range(len(list)) generates an index for each position in the list. The index can be used to read the element at that position and to assign a new value to that position. Assignment is the updating step: it changes the value stored at the selected list position while the loop continues to the next generated index.

selectsselectsselects0my_list[0]4selected value1my_list[1]7selected value2my_list[2]9selected value
How does each index produced by range(len(my_list)) map to a specific list element, and what value does assignment change at that position?

Following the Updating Pattern

A list contains 4, 7, and 9. Trace the positions produced by range(len(list)) and identify the element selected at each position.

Determine the length: The list has three elements, so range(len(list)) produces one index for each of its three positions.

Use index 0: The first generated index selects the element at position 0, which is 4 in this generated example.

Use index 1: The next generated index selects the element at position 1, which is 7.

Use index 2: The final generated index selects the element at position 2, which is 9.

Each generated index identifies one list position, making each position available for assignment.

Tracing a List Update

What do you think happens?

A list starts as 4, 7, 9. An index-based loop visits positions 0, 1, and 2, and assignment changes the selected value at each position. After the first iteration changes the value at position 0 to 5, which position is selected next?

  • Position 0 again
  • Position 1
  • Position 2
Reveal answer

Answer: Position 1

The index-based pattern progresses through the indices generated by range(len(list)). After position 0, the next generated position is 1.

index 0index 1index 24, 7, 9before the loop5, 7, 9position 0 updated5, 8, 9position 1 updated5, 8, 10position 2 updated
What does the list look like after each iteration when assignment replaces the value selected by the current index?

The important tracing habit is to record both the current index and the current list state. At each iteration, the index identifies one position. Assignment changes the value at that position, and the next iteration uses the next generated index. The list therefore carries earlier updates into later iterations.

Mutation Boundaries

Assignment is position-specific in an index-based traversal. To trace it, do not describe the whole list as changing at once. First identify the current index, then identify the value at that position, and finally record the replacement value. This keeps the mutation connected to the exact list position selected by the loop.

  • Using a direct value-reading loop when the task requires changing list elements.

    Direct traversal is intended for inspecting or displaying values; index-based traversal supplies the positions needed for updates.

    Fix: Use the pattern for i in range(len(list)) when the loop must update elements.

  • Confusing an index with the value stored at that index.

    The index identifies a position, while the list element is the value found at that position.

    Fix: Trace the index and the selected value as two separate pieces of information.

  • Predicting the final list without tracing intermediate states.

    Each iteration uses a particular generated index, and earlier assignments remain part of the list state during later iterations.

    Fix: Write down the list after every assignment.

Practice the Trace

MEDIUM

A list begins with the values 2, 5, and 8. Trace an index-based updating traversal that visits every position once. For each iteration, write the current index, the value selected at that index, and the list state after assignment replaces that value with 3, 6, and 9 respectively.

Hints
  • First identify how many positions the list has.
  • Write the generated indices in order.
  • Record the complete list after each position is assigned.
  1. Count the list elements to determine the range length.
  2. Record each index in the order the index-based loop visits it.
  3. Map each index to the value currently stored at that position.
  4. Apply the assignment for that position.
  5. Write the complete list state before moving to the next index.

Working Rules

  • Use a simple for loop when the task only needs to inspect or display each element.
  • Use range(len(list)) when the task needs access to each list position for updating.
  • When tracing a mutation, record the operation, the selected position or element, and the complete list state afterward.
  • Keep the index and the value separate in your notes; the index identifies where the value is stored.
  • For append(), remove(), and assignment, identify exactly which part of the list the operation changes before predicting the next state.

Key Takeaways

  • A simple for loop traverses a list by reading each element's value directly.
  • The pattern for i in range(len(list)) generates positions that can be used to read and update list elements.
  • Assignment changes the value stored at the selected list position.
  • To predict a mutation, trace the current index, selected value, operation, and complete list state after each iteration.
  • The essential distinction is reading values directly versus using indices to update positions.