Как мне объединить два списка в 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 Restrictions | In-Place? | Generalize?* | |
---|---|---|---|
a + b | - | No | sum(list_of_lists, []) 1 |
list(chain(a, b)) 2 | >=2.3 | No | list(chain(*list_of_lists)) |
[*a, *b] 3 | >=3.5 | No | No |
a += b | - | Yes | No |
a.extend(b) | - | Yes | No |
* 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
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.See
chain
andchain.from_iterable
from the docs. You will need tofrom 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.This method uses Additional Unpacking Generalizations (PEP 448), but cannot
generalize to N lists unless you manually unpack each one yourself.
a += b
anda.extend(b)
are more or less equivalent for all practical purposes.+=
when called on a list will internally calllist.__iadd__
, which extends the first list by the second.
Performance
2-List Concatenation1
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
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 andoperator
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 assum([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 thana.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.yield
ing list elements from a function is an acceptable method, butchain
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 toa + b
. It's use cases are mainly for dynamic method dispatch. Otherwise, prefera + b
which is shorter and more readable, in my opinion. YMMV.