list.append()

Add one item to the end — in place, returning None. The most-used list method, and the most-misassigned one.

List methodPython 2.0+Live demo
Common call
items.append(x)
Returns
None — the list itself grows
Replaces
appends ONE item; a list argument becomes a nested list
Watch out
x = lst.append(v) sets x to None — the classic bug
list.append(itemitemThe object to add. Added as ONE element — even if it is itself a list.type: Any · required)
None

Demo

Live evaluation
Try:
Inputs
listlistcomma-separated items
itemAnyitem to add
Output
['a', 'b', 'c'].append('d')
None

The output is None — really. That IS the lesson: append mutates the list in place (after ["a","b","c"].append("d") the list is ["a","b","c","d"]) and returns nothing. Assigning the result to a variable is the #1 append bug — see Pitfalls.

Parameters

NameTypeRequiredDescription
itemAnyyesThe object to add. Added as ONE element — even if it is itself a list.

Return value

NoneNone — always. The list grows in place; there is nothing useful to return.

Common patterns

Build a list in a loop
The bread-and-butter accumulation pattern.
results = []
for item in source:
    results.append(transform(item))
Know when a comprehension is better
Pure transform-and-collect loops read better as comprehensions.
results = [transform(x) for x in source]
Stack push
append + pop() from the end = LIFO stack, both O(1).
stack.append(job)
job = stack.pop()

Examples

1. Append one item
lst = [1, 2] lst.append(3) lst
Returns
[1, 2, 3]
2. Appending a list nests it
lst = [1, 2] lst.append([3, 4]) lst
Returns
[1, 2, [3, 4]]
3. The return value is None
result = [1].append(2) print(result)
Returns
None

Pitfalls

1. Assigning the result loses the list
append returns None by design — never assign it.
Wrong
lst = lst.append(x)
lst is None
Fix
lst.append(x)  # no assignment
list grew in place
2. append vs extend
append adds its argument as ONE element; extend splices an iterable in.
Nested
lst = [1, 2]
lst.append([3, 4])
[1, 2, [3, 4]]
Flat
lst = [1, 2]
lst.extend([3, 4])
[1, 2, 3, 4]
3. Appending to a shared default argument
The infamous mutable-default trap: one list shared across calls.
Shared state
def add(x, items=[]):
    items.append(x)
    return items
grows across unrelated calls
Fix
def add(x, items=None):
    items = items if items is not None else []
    items.append(x)
    return items
fresh list per call

When to use

Use it
  • Accumulating results one at a time
  • Stack push (with pop for the pop side)
  • Appending in loops with logic a comprehension cannot express
Reach for something else
  • Adding all items of an iterable → list.extend
  • Pure transform loops → list comprehension
  • Inserting elsewhere than the end → list.insert (O(n))
  • Fast appends AND pops at both ends → collections.deque

Notes

Complexity
Amortized O(1) — the array over-allocates as it grows
Return
None; the list mutates
CPython impl
Objects/listobject.c :: list_append
Memory
Occasional reallocation with growth factor ~1.125
Thread-safe
append itself is atomic in CPython, but do not rely on it for logic

FAQ

Python convention: methods that mutate in place return None, so you cannot mistake them for ones returning new objects. It rules out fluent chaining on purpose.

History

2.0
Core list method, unchanged semantics since.