list.extend()
Add every item from any iterable to the end of the list. Not the iterable itself — its items, one by one.
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(iterableiterable — Any 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
| Name | Type | Required | Description |
|---|---|---|---|
| iterable | iterable | yes | Any iterable — list, tuple, set, generator, string, dict (keys), file. Items are appended one at a time to the end. |
Return value
None — Returns 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
None5. 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.