PyPython example

How to concatenate two lists in Python

4 min read▶ Runs in an isolated hosted runtimeUpdated Jul 2026

Quick answer

Use the + operator: combined = a + b. It returns a new list and leaves a and b untouched. To grow an existing list instead, use a.extend(b).

The real choice here isn't syntax, it's who owns the result: a + b builds a new list, while extend() and += mutate a in place — which anything else holding a reference to a will see. Each example runs on this page: hit Run, then edit the code and run it again.

1The + operatorRecommended

+ on two lists returns a brand-new list holding the items of the first followed by the items of the second. Both inputs are left exactly as they were.

concat.py

Output

Prints [1, 2, 3, 4, 5, 6] then [1, 2, 3] [4, 5, 6] — the originals are unchanged. Both operands must be lists: [1, 2] + (3, 4) raises TypeError: can only concatenate list (not "tuple") to list.

2extend() and += (in place)

a.extend(b) appends every item of b onto a itself and returns None. a += b is the same operation with different spelling — for lists, += calls __iadd__, so it mutates rather than rebinding. Use either when you want to grow a list you already have instead of paying for a copy.

extend.py

Output

Output: [1, 2, 3, 4, 5, 6], ['x', 'y', 'z'], ['x', 'y', 'z', 'p', 'q']. Note that extend() and += accept any iterable — tuples, sets, generators, even strings (which add one character per item). Don't confuse it with append(), which would push the whole list in as a single nested element.

3Unpacking with [*a, *b]

The * unpacking operator spreads each iterable into a fresh list literal. It reads well and, unlike +, scales to any number of sources in one expression — and lets you drop extra items in wherever you like.

unpack.py

Output

Prints [1, 2, 3, 4], [1, 2, 3, 4, 5, 6] and [0, 1, 2, 3, 4, 99]. Chaining a + b + c would build a throwaway intermediate list for a + b; the unpacked literal allocates once.

4itertools.chain (lazy)

chain() doesn't concatenate at all — it returns an iterator that walks the inputs back to back without copying a single element. That's the one to reach for when the lists are large, or when there are many of them and you only need to iterate the result once. chain.from_iterable() takes the lists as one sequence instead of as separate arguments.

chain.py

Output

Prints 1 2 3 4 5 6, then 21, then [1, 2, 3, 4, 5, 6]. Remember it's single-pass: once you've consumed the iterator it's empty, so wrap it in list(...) if you need a real list you can index or reuse.

5Which should you use?

MethodResultCostBest for
a + bNew listOne copyTwo lists, originals kept
a.extend(b) / a += bIn placeFastestGrowing a list you own
[*a, *b]New listOne copyThree or more sources
chain(a, b)IteratorNo copyHuge or many lists, one pass

6Common variation: the += aliasing gotcha

This is the bug += hides. If two names point at the same list — a second variable, a function parameter, an item inside another structure — then += changes what both of them see, while a = a + b quietly rebinds only the name on the left.

aliasing.py

Output

After the += line both names print [1, 2, 3, 4] — the 4 landed in original too. After the + line they diverge: original is still [1, 2, 3, 4] while alias is [1, 2, 3, 4, 5], because + built a new list and only alias now refers to it. When a function receives a list and must not surprise its caller, concatenate with +.

Frequently asked questions

What is the difference between + and extend() in Python?

a + b builds and returns a new list, leaving both originals untouched. a.extend(b) mutates a in place and returns None, so it is faster and allocation-free but visible to anything else holding a reference to a.

Is a += b the same as a = a + b for lists?

Not quite. For lists += calls __iadd__, which extends the list in place, so every other name bound to that same list sees the new items. a = a + b creates a new list and rebinds only a. The printed result looks identical until something else is aliasing the list.

How do I concatenate more than two lists at once?

Use unpacking — [*a, *b, *c] — which allocates the result once instead of building an intermediate list per +. For a list of lists, list(itertools.chain.from_iterable(lists)) is the standard one-liner.

Can you concatenate a list and a tuple with +?

No — [1, 2] + (3, 4) raises TypeError: can only concatenate list (not "tuple") to list. Convert first with list(t), unpack with [*a, *t], or use a.extend(t), which accepts any iterable.