Concepts / List Methods: append, extend, pop, and del

List Methods: append, extend, pop, and del

Reassigning a function parameter (e.g., t = t[1:]) does not modify the original list passed to the function; it only changes what the local variable refers to.

  • Programming

The List Object at Stake

When a list is passed to a function, the function can either change the existing list object or make its local parameter refer to a different list. These actions look similar when you read the function, but they have different effects on the caller's list. The central question is not simply which list operation was written. It is whether the existing list was modified or whether a new list was produced.

Methods such as append() and pop() modify the actual list object in place, so the change is visible to the caller. Slicing and the + operator create new lists, leaving the original list unchanged.

in-place operationslice creates new listitems[a, b, c]values[a, b, c]items[a, b, c, d]result[b, c]
Which operations change the existing list object, and which create or refer to a different list object?

Four Ways to Change List Contents

OperationEffect on the listResulting purpose
append()Modifies the existing list in placeAdd one item to the list
extend()Modifies the existing list in placeAdd each item from another iterable
pop()Modifies the existing list in placeRemove an element and return it
delRemoves an element from the listRemove an element without returning it
SlicingCreates a new listProduce a list based on part of another list
+Creates a new listCombine lists into a separate list

The key distinction is whether the existing list is changed or a new list is produced.

append() and extend() both add contents in place, but they add contents at different levels. append() adds one item as a single new element. If that item is itself a list, the nested list remains one element. extend() takes the items from another iterable and adds those items individually. Thus, choosing between them depends on whether the incoming object should remain one item or be unpacked into several items.

appendone elementextendeach itemitems[1, 2]items[1, 2][3, 4]one item[3, 4]source itemsitems[1, 2, [3, 4]]items[1, 2, 3, 4]
How does append add one item compared with extend adding each item from another iterable?

pop() and del both remove list elements. pop() is useful when the removed element is also needed, because it removes the element and returns it. del removes the selected element without returning it. Both are removal operations, but their function purposes differ: one produces a removed value for further use, while the other simply performs the deletion.

Why Parameter Reassignment Stops at the Function

Consider a function whose parameter is named t. At the beginning of the call, t refers to the list supplied by the caller. If the function evaluates t[1:], slicing creates a new list. Reassigning t to that slice changes what the local name t refers to, but it does not replace or edit the caller's original list. When the function finishes, the caller's list is still the original object.

parameter refers toslice createsreassignmentunchangedoriginal[first, second, third]toriginal listt[1:][second, third]original[first, second, third]tslice list
What happens to the original list when a function changes its local parameter from t to t[1:]?

Tracing a Slice Reassignment

A caller supplies the list [10, 20, 30] to a function. Inside the function, the parameter is reassigned to the slice beginning at index 1. What list remains visible to the caller?

Initial reference: The function parameter refers to the caller's original list, whose contents are [10, 20, 30].

Slice creation: The slice beginning at index 1 produces a new list containing [20, 30].

Local reassignment: The parameter is made to refer to the new slice list. This changes the local parameter reference, not the original list.

After the function: The caller still has the original list because no in-place list method changed it.

The caller sees [10, 20, 30]. The function's local parameter refers to [20, 30] only after reassignment.

Choosing a Function Contract

A function that is intended to change the caller's list should use an in-place operation such as append(), extend(), or pop(). Because these methods modify the actual list object, the caller can observe the change after the function call. A function that is intended to preserve the input should use an operation such as slicing or + to create a new list and then return that new list.

Function intentionSuitable approachCaller’s original list
Change the supplied listUse an in-place methodChanged and visible after the call
Produce a revised listUse slicing or +Left unchanged
Remove and use a valueUse pop()Changed; removed value is returned
Remove without needing a valueUse delChanged; no removed value is returned

The function's intended contract should determine whether it mutates the input or returns a separate list.

slice createsfunction returnsoriginal[a, b, c]new list[b, c]result[b, c]
How do the original list, the newly created list, and the function's return value remain separate?

Choose one clear purpose for each list-processing function. If the purpose is to modify the supplied list, make that intent clear through the function's naming and documentation. If the purpose is to return a revised list while preserving the input, state that intent clearly as well.

Common List-Operation Mistakes

  • Assuming that assigning a slice back to a function parameter changes the caller's list

    Slicing creates a new list, and parameter reassignment changes only what the local parameter refers to.

    Fix: Use an in-place list operation when the function must change the list supplied by the caller, or return the new sliced list when the original should remain unchanged.

  • Using append() when the incoming list should be added item by item

    append() adds one item, even when that item is itself a list.

    Fix: Use extend() when the items from another iterable should be added individually.

  • Using del when the removed value is needed later

    del removes the element without returning it.

    Fix: Use pop() when removal and retrieval of the removed element are both required.

  • Changing a list in place when the function should preserve the input

    In-place methods modify the actual list object and make the change visible to the caller.

    Fix: Use slicing or + to create a new list, and return that new list.

Practice the Contract

MEDIUM

Design two functions for a list of task names. The first function should add a new task to the supplied list so that the caller's list changes. The second function should create a list containing all tasks except the first one while leaving the caller's original list unchanged.

Hints
  • For the first function, choose an in-place method.
  • For the second function, use slicing and return the resulting list.
  • After each function call, compare the caller's original list with the value produced by the function.

What do you think happens?

A list contains [red, blue]. A function uses an in-place operation to add green, while another function creates a slice and returns it. Which function changes the caller's original list?

  • Only the function using the in-place operation
  • Only the function returning the slice
  • Both functions
  • Neither function
Reveal answer

Answer: Only the function using the in-place operation

An in-place operation modifies the actual list object and the change is visible to the caller. A slice creates a new list, so returning it does not modify the original list.

A Reliable Decision Rule

  1. Decide whether the function should change the supplied list or preserve it.
  2. For a visible change to the caller's list, use an in-place operation such as append(), extend(), pop(), or del.
  3. For a separate revised list, use slicing or + and return the new list.
  4. Use append() for one added item and extend() for adding items individually from another iterable.
  5. Use pop() when removal and the removed value are both needed; use del when removal is needed without a returned value.
  6. Make the function's mutation or return behavior clear through its naming and documentation.

Key Takeaways

  • In-place methods modify the existing list object, so their changes are visible to the caller.
  • append() adds one item, while extend() adds items individually from another iterable.
  • pop() removes and returns an element; del removes an element without returning it.
  • Slicing and the + operator create new lists and leave the original list unchanged.
  • Reassigning a function parameter to a slice changes only the local parameter reference, not the caller's list.