Python List extend(): Add Every Item From an Iterable

Published

Python’s list.extend() method adds every item from an iterable to the end of a Python list. An iterable is anything Python can loop over. The method changes the existing list and returns None. Use it to add several items, and use append() to add one object:

queue = ["ann", "bo"]

queue.extend(["cy", "di"])

print(queue)
# Program output:
# ['ann', 'bo', 'cy', 'di']

The list grew by two items. With append(), ["cy", "di"] would become one nested list.

Syntax and Basic Usage

items.extend(iterable)
# adds each item of iterable to the end
  • iterable (required): anything Python can loop over, such as a list, tuple, range or generator.
  • Returns: None, because it changes the list in place.
  • Raises: TypeError for a non-iterable argument or the wrong number of arguments.

The new items go after the existing ones, in the order the iterable supplies them:

scores = [70, 85]
new_scores = [91, 64, 78]

scores.extend(new_scores)

print(scores)
print(len(scores))
print(new_scores)
# Program output:
# [70, 85, 91, 64, 78]
# 5
# [91, 64, 78]

The new_scores list is only read, so it stays unchanged.

What Can You Pass to Python extend()?

Python extend() accepts any iterable, including lists, tuples, strings, ranges, sets, dictionaries, and generators. It adds items in the order the iterable supplies them.

Tuples, Ranges, and Sets

nums = [0]

nums.extend((1, 2))
nums.extend(range(3, 6))

print(nums)
# Program output:
# [0, 1, 2, 3, 4, 5]

A set has no fixed order, so wrap it in sorted() when order matters, as in nums.extend(sorted(my_set)).

Dictionaries and Generators

Passing a dictionary to extend() adds its keys in insertion order. Use .values() for the values or .items() for (key, value) tuples:

prices = {"tea": 3, "pie": 5}

names = []
names.extend(prices)
print(names)

totals = []
totals.extend(prices.values())
print(totals)
# Program output:
# ['tea', 'pie']
# [3, 5]

A generator expression also works, and no temporary input list gets built. The destination list still needs space for every item:

squares = [1]

squares.extend(n * n for n in range(2, 5))

print(squares)
# Program output:
# [1, 4, 9, 16]

Our Python guide covers the loops and basic types used in these examples.

Practical Examples

Collecting Results from Several Batches

Call extend() once for each batch to collect its items in one list. Any lists inside a batch stay nested; extend() does not flatten them recursively.

batches = [
    ["a01", "a02"],
    ["b01"],
    ["c01", "c02", "c03"],
]

orders = []
for batch in batches:
    orders.extend(batch)

print(orders)
print(len(orders))
# Program output:
# ['a01', 'a02', 'b01', 'c01', 'c02', 'c03']
# 6

With append() in that loop, you would get three nested lists instead of six order numbers.

Filtering As You Extend

Because extend() takes a generator, you can filter data on the way in:

emails = ["a@x.com"]
signups = ["b@x.com", "", "c@x.com", ""]

emails.extend(e for e in signups if e)

print(emails)
# Program output:
# ['a@x.com', 'b@x.com', 'c@x.com']

The if e test skips the empty strings, which count as false.

Common Pitfalls and Debugging

A Generator Fails After Adding Some Items

def values():
    yield 2
    raise ValueError("invalid input")

items = [1]
try:
    items.extend(values())
except ValueError:
    pass
print(items)  # [1, 2]: the successful yield remains

In CPython, if a generator raises an error halfway through extend(), items already added stay in the list. The failed call does not undo those additions.

TypeError: 'int' object is not iterable

A single number cannot be looped over, so extend() raises a TypeError:

counts = [1, 2]
counts.extend(3)
# Program output:
# Traceback (most recent call last):
#   ...
# TypeError: 'int' object is not iterable

Use counts.append(3) for one item, or wrap it as counts.extend([3]). Passing None or a float also raises TypeError, with that type named in the message.

A String Splits into Characters

A string raises no error, because looping over it gives one character at a time:

tags = ["python"]

tags.extend("lists")
print(tags)
# Program output:
# ['python', 'l', 'i', 's', 't', 's']

Use tags.append("lists") to add the whole word, or tags.extend(["lists"]).

TypeError: list.extend() takes exactly one argument

The method accepts exactly one argument, so passing two lists raises a TypeError:

items = [1]
items.extend([2], [3])
# Program output:
# Traceback (most recent call last):
#   ...
# TypeError: list.extend() takes exactly one argument (2 given)

Call extend() once per list, or combine them with itertools.chain():

from itertools import chain

items = [1]
items.extend(chain([2], [3, 4]))

print(items)
# Program output:
# [1, 2, 3, 4]

AttributeError: 'NoneType' object has no attribute

The extend() method changes the list and returns None. Assigning that return value to cart makes the name refer to None, so the next line fails:

cart = ["milk"]
cart = cart.extend(["eggs"])
cart.append("bread")
# Program output:
# Traceback (most recent call last):
#   ...
# AttributeError: 'NoneType' object has no attribute 'append'

Call cart.extend(["eggs"]) on its own line instead, and note that the attribute in the message depends on what you did next.

Python extend(), append(), +=, and + Compared

For Python lists, use extend() to add items from an iterable and append() to add one object. The += operator also extends the existing list, while + creates a new list from two lists.

ToolAddsChanges original?Accepts
items.extend(xs)Each item of xsYesAny iterable
items.append(x)x as one itemYesAny value
items += xsEach item of xsYesAny iterable
items + xsEach item of xsNo, makes a new listAnother list only

The + operator builds a new list, so other names still point at the old one, and it rejects a tuple or range on the right:

a = [1, 2]
b = a

a += [3]
print(b)

a = a + [4]
print(b)
print(a)
# Program output:
# [1, 2, 3]
# [1, 2, 3]
# [1, 2, 3, 4]

After a += [3], both names share one list, but a = a + [4] gives a a new list. Adding a tuple with + raises TypeError: can only concatenate list (not "tuple") to list.

Use extend() to grow the list you have, because its name says the list changes in place. Use + only when you need a new list and the original left alone.

Our insert() guide covers adding one item at a chosen position.

Add Multiple Items to a Python List

Use extend() to add each item of any iterable to the end of your list, and call it on its own line because it returns None. Use append() for a single item, especially a single string.

Frequently Asked Questions

Can Python extend() add items to the start of a list?

Python list.extend() adds items only to the end of a list. To add several items at the front, use an empty slice such as items[:0] = ["a", "b"]. The new items keep their order, and the existing items shift along.

Does Python extend() copy the items it adds?

Python list.extend() adds references to the original objects rather than copying them. If an added item is a list or dictionary, changes to that object appear in both collections. Numbers and strings cannot be changed in place.

Does Python extend() work on tuples or strings?

Python tuples and strings have no extend() method because they cannot change in place. A list can accept either as an argument to extend(). A string contributes individual characters; use append() to add the whole string as one item.

Sources

  1. [1]
  2. [2]
    Mutable Sequence Types
    (docs.python.org)
  3. [3]
    itertools.chain
    (docs.python.org)