Вопрос-Ответ

How do I concatenate two lists in Python?

Как мне объединить два списка в Python?

Как мне объединить два списка в Python?

Пример:

listone = [1, 2, 3]
listtwo = [4, 5, 6]

Ожидаемый результат:

>>> joinedlist
[1, 2, 3, 4, 5, 6]
Переведено автоматически
Ответ 1

Используйте оператор + для объединения списков:

listone = [1, 2, 3]
listtwo = [4, 5, 6]

joinedlist = listone + listtwo

Вывод:

>>> joinedlist
[1, 2, 3, 4, 5, 6]

ПРИМЕЧАНИЕ: Это создаст новый список с мелкой копией элементов в первом списке, за которым последует мелкая копия элементов во втором списке. Используйте copy.deepcopy() для получения глубоких копий списков.

Ответ 2

Python >= 3.5 альтернатива: [*l1, *l2]

Другая альтернатива была представлена благодаря принятию PEP 448, которая заслуживает упоминания.

PEP, озаглавленный Дополнительные обобщения распаковки, в целом уменьшил некоторые синтаксические ограничения при использовании отмеченного звездочкой * выражения в Python; с его помощью объединение двух списков (применяется к любому итерируемому) теперь также может быть выполнено с помощью:

>>> l1 = [1, 2, 3]
>>> l2 = [4, 5, 6]
>>> joined_list = [*l1, *l2] # unpack both iterables in a list literal
>>> print(joined_list)
[1, 2, 3, 4, 5, 6]

Эта функциональность была определена для Python 3.5, но она не была перенесена в предыдущие версии семейства 3.x. В неподдерживаемых версиях будет вызван a SyntaxError.

Как и в случае с другими подходами, это тоже создает как можно меньшую копию элементов в соответствующих списках.


Плюсом этого подхода является то, что вам действительно не нужны списки для его выполнения; подойдет все, что можно повторить. Как указано в PEP:


Это также полезно как более читаемый способ суммирования итераций в список, например, my_list + list(my_tuple) + list(my_range) который теперь эквивалентен just [*my_list, *my_tuple, *my_range].


Таким образом, при добавлении с + возникнет TypeError из-за несоответствия типов:

l = [1, 2, 3]
r = range(4, 7)
res = l + r

Следующее не будет:

res = [*l, *r]

because it will first unpack the contents of the iterables and then simply create a list from the contents.

Ответ 3

It's also possible to create a generator that simply iterates over the items in both lists using itertools.chain(). This allows you to chain lists (or any iterable) together for processing without copying the items to a new list:

import itertools
for item in itertools.chain(listone, listtwo):
# Do something with each list item
Ответ 4

How do I concatenate two lists in Python?


As of 3.9, these are the most popular stdlib methods for concatenating two (or more) lists in Python.











































Version RestrictionsIn-Place?Generalize?*
a + b-Nosum(list_of_lists, [])1
list(chain(a, b))2>=2.3Nolist(chain(*list_of_lists))
[*a, *b]3>=3.5NoNo
a += b-YesNo
a.extend(b)-YesNo

* A solution will qualify as a generalized solution if it works for an unknown number of lists (say, inside a loop or list comprehension)


Footnotes



  1. This is a slick solution because of its succinctness. But sum performs concatenation in a pairwise fashion, which means this is a
    quadratic operation as memory has to be allocated for each step. DO
    NOT USE if your lists are large.



  2. See chain
    and
    chain.from_iterable
    from the docs. You will need to from itertools import chain first.
    Concatenation is linear in memory, so this is the best in terms of
    performance and version compatibility. chain.from_iterable was introduced in 2.6.



  3. This method uses Additional Unpacking Generalizations (PEP 448), but cannot
    generalize to N lists unless you manually unpack each one yourself.



  4. a += b and a.extend(b) are more or less equivalent for all practical purposes. += when called on a list will internally call
    list.__iadd__, which extends the first list by the second.





Performance

2-List Concatenation1

enter image description here

There's not much difference between these methods but that makes sense given they all have the same order of complexity (linear). There's no particular reason to prefer one over the other except as a matter of style.

N-List Concatenation

enter image description here

Plots have been generated using the perfplot module. Code, for your reference.

1. The iadd (+=) and extend methods operate in-place, so a copy has to be generated each time before testing. To keep things fair, all methods have a pre-copy step for the left-hand list which can be ignored.


Comments on Other Solutions


  • DO NOT USE THE DUNDER METHOD list.__add__ directly in any way, shape or form. In fact, stay clear of dunder methods, and use the operators and operator functions like they were designed for. Python has careful semantics baked into these which are more complicated than just calling the dunder directly. Here is an example. So, to summarise, a.__add__(b) => BAD; a + b => GOOD.



  • Some answers here offer reduce(operator.add, [a, b]) for pairwise concatenation -- this is the same as sum([a, b], []) only more wordy.



  • Any method that uses set will drop duplicates and lose ordering. Use with caution.



  • for i in b: a.append(i) is more wordy, and slower than a.extend(b), which is single function call and more idiomatic. append is slower because of the semantics with which memory is allocated and grown for lists. See here for a similar discussion.



  • heapq.merge will work, but its use case is for merging sorted lists in linear time. Using it in any other situation is an anti-pattern.



  • yielding list elements from a function is an acceptable method, but chain does this faster and better (it has a code path in C, so it is fast).



  • operator.add(a, b) is an acceptable functional equivalent to a + b. It's use cases are mainly for dynamic method dispatch. Otherwise, prefer a + b which is shorter and more readable, in my opinion. YMMV.



python list