Concepts / Functions and Return Values

Functions and Return Values

Python provides several methods for common list operations. Three of the most frequently used are append, extend, and sort. Each modifies the list in place and returns None, but they perform different operations on the list's contents.

  • Programming

A Changed List Is Not a Returned List

When you call a list method, two results must be considered separately: what happens to the list itself and what value the method call produces. The methods append, extend, and sort modify the existing list in place. Each of them returns None. That means the list can change even though the method call does not produce a new list value.

[1, 2]list before append[1, 2, 3]list after appendNonemethod resultappend(3)returns
What changes in the original list, and what value does the method call produce?

Tracing an In-Place Method Call

Worked example

Calling append

Suppose a list starts as [10, 20]. What are the list and the return value after append(30) is called?

  1. 1
    Starting state

    The list contains 10 and 20.

  2. 2
    Modify the list

    append adds 30 as one new item in the existing list.

  3. 3
    Identify the return value

    append modifies the list in place and returns None.

Result

The list is [10, 20, 30], and the return value of the method call is None.

Code walkthrough
items = [10, 20]
result = items.append(30)
print(items)
print(result)
  1. 1
    After the append call, items refers to the changed list [10, 20, 30].
  2. 2
    The append call itself produces None, so result refers to None.
  3. 3
    The changed list is not stored in result.
  • items begins as a list containing 10 and 20.
  • append adds 30 to the existing list.
  • result receives the method's return value, which is None.
  • The list and the return value are displayed separately.
Output
[10, 20, 30]
None
items[10, 20]append(30)method callitems[10, 20, 30]Nonereturn valuecalled onchangesreturns
How are the list's changed state and the method's return value connected but different?

Choosing Between Append and Extend

append and extend both add elements to a list, but they treat their arguments differently. append adds its argument as one item. extend takes the items from another iterable and adds those items to the list. This difference matters when the argument itself contains several values: append can place that argument into the list as a single item, while extend adds the contained items separately.

python
CallResulting listWhat was added
first.append([3, 4])[1, 2, [3, 4]]One item: the list [3, 4]
second.extend([3, 4])[1, 2, 3, 4]The items 3 and 4 separately

append and extend make different choices about the argument's structure.

append[3, 4] as one item[1, 2, [3, 4]]nested listextend3 and 4 separately[1, 2, 3, 4]separate itemsproducesproduces
Does the list receive one new item or each item from another iterable?

Sorting the Existing List

sort is another in-place list method. Its operation is different from append and extend: instead of adding elements, sort rearranges the existing list. Immediately after the call, inspect the same list variable to see its reordered contents. The return value is still None.

python
Output
[10, 30, 40]
None
[40, 10, 30]before sort[10, 30, 40]after sortNonereturn valuesort()returns
How does sort rearrange the existing list, and what is the list's state immediately after the call?

The Assignment Trap

The most common mistake is assigning the result of an in-place list method back to the list variable. Because append, extend, and sort return None, the assignment replaces the variable's reference with None. The list operation has already happened, but the variable no longer refers to the list afterward.

  • Common mistake

    Assigning append's result back to the list variable

    What it looks like
    items = items.append(3)
    Why it fails

    append modifies the list in place and returns None, so items becomes None.

    Do this instead

    Call items.append(3) without assigning its result.

  • Common mistake

    Assigning extend's result back to the list variable

    What it looks like
    items = items.extend([3, 4])
    Why it fails

    extend modifies the list in place and returns None, so items becomes None.

    Do this instead

    Call items.extend([3, 4]) without assigning its result.

  • Common mistake

    Assigning sort's result back to the list variable

    What it looks like
    scores = scores.sort()
    Why it fails

    sort rearranges the list in place and returns None, so scores becomes None.

    Do this instead

    Call scores.sort() and then use scores.

items[1, 2]append(3)changes the listNonemethod resultitemsNoneitems.append(3)returnsassignment
What happens to the variable when the result of append, extend, or sort is assigned back to it?
Before
items = [1, 2]
items = items.append(3)

The list is modified, but items is assigned the method result None.

After
items = [1, 2]
items.append(3)

The list is modified and items continues to refer to the list.

A Reliable Tracing Routine

  1. 1
    Write down the list's state before the method call.
  2. 2
    Identify which operation the method performs: append adds one item, extend adds items from another iterable, or sort rearranges the existing contents.
  3. 3
    Update the list's state in place.
  4. 4
    Record the method's return value as None.
  5. 5
    Check whether an assignment stores that return value back into the list variable.
  6. 6
    If such an assignment is present, update the variable to None.

What do you think happens?

After these statements, what are the values of items and result?
items = [2, 1]
result = items.sort()
  • items is [2, 1] and result is [1, 2]

  • items is [1, 2] and result is None

  • items is None and result is [1, 2]

  • items is [1, 2] and result is [1, 2]

Reveal answer
Answer:

items is [1, 2] and result is None

sort rearranges the existing list in place, while its return value is None.

Practice the State Trace

MEDIUM

Trace each snippet without running it. For every snippet, write the final list state and the method call's return value. Then identify whether the list variable still refers to the list.

A. values = [1, 2]
   result = values.extend([3, 4])
B. values = [3, 1, 2]
   result = values.sort()
C. values = [1, 2]
   values = values.append(3)
Hints
  • For extend, decide whether the argument becomes one item or contributes its items separately.
  • For sort, rearrange the existing contents and then record None as the return value.
  • For the final snippet, look for an assignment that overwrites the list variable.
Worked example

Practice Answer for Snippet A

Trace values = [1, 2] followed by result = values.extend([3, 4]).

  1. 1
    Starting state

    values contains [1, 2].

  2. 2
    Apply extend

    The items 3 and 4 are added separately, so the list becomes [1, 2, 3, 4].

  3. 3
    Record the result

    The method returns None, so result is None. Because the result was not assigned to values, values still refers to the changed list.

Result

values is [1, 2, 3, 4], and result is None.

Key Takeaways

  1. 1
    append, extend, and sort modify a list in place.
  2. 2
    append adds its argument as one item, while extend adds the items from another iterable.
  3. 3
    sort rearranges the existing list.
  4. 4
    All three methods return None.
  5. 5
    Do not assign the result of these methods back to the list variable, or the variable will be overwritten with None.

At a glance

  • Separate a method's side effect from its return value.
  • Use append for adding one item, extend for adding items from another iterable, and sort for rearranging a list.
  • Expect append, extend, and sort to return None.
  • Never replace a list variable with the result of one of these in-place methods.

Related concepts

More concepts starting with F