list.extend()

Add every item from any iterable to the end of the list. Not the iterable itself — its items, one by one.

List methodPython 1.5+Live demo
Common call
items.extend(more_items)
Returns
None — the list itself grows
Replaces
a for-loop of append() calls
Watch out
extending with a string adds each CHARACTER
list.extend(iterableiterableAny iterable — list, tuple, set, generator, string, dict (keys), file. Items are appended one at a time to the end.type: iterable · required)
None

Demo

Live evaluation
Try:
Inputs
listliststarting list
itemslistitems to add
Output
['a', 'b', 'c'].extend(['d', 'e'])
None

The demo shows the LIST STATE after extending. Python actually returns None; the meaningful effect is mutation. extend unpacks the iterable and appends each item — very different from append, which would add the whole iterable as a single nested item. See the pitfalls for the classic string trap.

Parameters

NameTypeRequiredDescription
iterableiterableyesAny iterable — list, tuple, set, generator, string, dict (keys), file. Items are appended one at a time to the end.

Return value

NoneReturns None — the useful effect is mutation. The demo shows the list state after extending.

Common patterns

Merge two lists
Extend the destination — one call, no allocation of a merged copy.
combined = list_a.copy()
combined.extend(list_b)
Accumulate from a generator
Extend eats any iterable, including lazy generators — one call, no intermediate list.
results.extend(process(chunk) for chunk in stream)
Flatten one level
Extend each sub-list into a flat accumulator.
flat = []
for row in rows:
    flat.extend(row)

Examples

1. Extend with a list
xs = [1, 2] xs.extend([3, 4]) xs
Returns
[1, 2, 3, 4]
2. Extend with a tuple
xs = [1] xs.extend((2, 3)) xs
Returns
[1, 2, 3]
3. Extend with an empty iter
xs = [1, 2] xs.extend([]) xs
Returns
[1, 2]
4. Returns None (surprise)
[1, 2].extend([3, 4])
Returns
None
5. Extend with a string
xs = ["a"] xs.extend("bc") xs
Returns
["a", "b", "c"] # each char!

Pitfalls

1. Extending with a string appends each character
A string IS an iterable — of single characters. extend("abc") adds "a", "b", "c", not the string as a whole. Probably the most-copied bug in the language after the `xs = xs.sort()` one.
Char explosion
names = ["Ann", "Bob"]
names.extend("Cara")
names
["Ann", "Bob", "C", "a", "r", "a"]
Wrap it
names.append("Cara")
# or
names.extend(["Cara"])
["Ann", "Bob", "Cara"]
2. The `xs = xs.extend(...)` bug
extend returns None. Assigning its result back sets your variable to None — the same class of bug as sort. Python mutates in place on purpose.
Now xs is None
xs = [1, 2]
xs = xs.extend([3, 4])
print(xs)
None
Two options
xs.extend([3, 4])   # mutate, keep name
# or
xs = xs + [3, 4]      # new list, replace name
[1, 2, 3, 4]
3. extend vs append confusion
append adds ONE item (the whole argument). extend unpacks and adds items. Reaching for the wrong one silently produces a wrong-shaped list.
Nested list
xs = [1, 2]
xs.append([3, 4])
xs
[1, 2, [3, 4]]
Flat list
xs = [1, 2]
xs.extend([3, 4])
xs
[1, 2, 3, 4]
4. Not iterable → TypeError
extend takes an iterable — passing a plain non-iterable (int, None, etc.) raises TypeError.
Type error
xs = [1, 2]
xs.extend(3)
TypeError: 'int' object is not iterable
Wrap or append
xs.append(3)
# or
xs.extend([3])
[1, 2, 3]

When to use

Use it
  • Adding multiple items at once from any iterable
  • Merging into an existing list without allocating a new one
  • Accumulating from generators lazily
  • Flattening one level of nested sequences
Reach for something else
  • Adding a single item that IS a sequence → append
  • Building a new list without mutating → xs + more or [*xs, *more]
  • In one-liners / chains — extend returns None
  • When the input might be a string but you meant to add it as one item

Notes

Complexity
O(k) where k is the length of the iterable
Return
None; the list is mutated in place
CPython impl
Objects/listobject.c :: list_extend — grows the internal array as needed
Memory
May reallocate the underlying array; amortized O(1) per item
Thread-safe
Not safe under concurrent mutation of the same list

FAQ

For lists they are equivalent — both mutate in place and accept any iterable. `xs += other` is a syntactic shortcut for `xs.extend(other)`.

History

1.5
extend() introduced.
2.0
Accepts any iterable, not just sequences.