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


2532

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

Пример:

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

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

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

6
Вы хотите просто добавить или вы хотите объединить два списка в отсортированном порядке ? Какой выход вы ожидаете для [1,3,6] и [2,4,5]? Можем ли мы предположить, что оба подсписка уже отсортированы (как в вашем примере)?
SMCI

1
... а что если в списках есть дубликаты, например [1,2,5] and [2,4,5,6]? Вы хотите, чтобы дубликаты были включены, исключены или не заботились?
SMCI

Ответы:


3907

Вы можете использовать +оператор, чтобы объединить их:

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

joinedlist = listone + listtwo

Вывод:

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

110
это создает глубокую копию listone и добавляет listtwo?
Даниэль Ф

152
@Daniel создаст новый список с мелкой копией элементов в первом списке, а затем с мелкой копией элементов во втором списке. Используйте copy.deepcopy, чтобы получить глубокие копии списков.
Даниэль Г,

219
другая полезная деталь здесь: listone += listtwoрезультатыlistone == [1, 2, 3, 4, 5, 6]
rickcnagy

16
@ br1ckb0t это изменит то, на что указывает listone? Итак: list3 = listone listone+=listtwo список3 тоже изменился?
MikeH

11
это действительно меняет список3. Однако, если это не проблема, проще добавить два списка, а не создавать новый.
Риккнаги

320

Также возможно создать генератор, который просто перебирает элементы в обоих списках, используя itertools.chain(). Это позволяет объединять списки (или любые итерируемые) для обработки без копирования элементов в новый список:

import itertools
for item in itertools.chain(listone, listtwo):
    # Do something with each list item

4
chainнаходится на более медленной стороне (но не намного) для двух списков, но является самым быстрым решением для объединения нескольких списков (n >> 2).
cs95

@ cs95 медленный по сравнению с чем?
Моберг

@Moberg По сравнению с другими способами объединения списков, для ознакомления, пожалуйста, посмотрите мои тесты здесь .
cs95

265

>= 3.5Альтернатива Python :[*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семейства. В неподдерживаемых версиях SyntaxErrorбудет поднят.

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


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

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

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

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

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

res = [*l, *r]

потому что он сначала распакует содержимое итерируемых элементов, а затем просто создаст listиз содержимого.


1
Хорошим примером подхода распаковки, работающего с итеративными типами, являются функции, которые возвращают итератор по одному из списков, которые вы объединяете. Например, вы могли бы обратить вспять один из списков вы конкатенации: res = [*l1, *reversed(l2)]. Так как reversedвозвращает итератор, res = l1 + reversed(l2)выдаст ошибку.
алан

2
Стоит отметить, что это аналогично объединению словарей в python. dict3 = {** dict1, ** dict2}. Обратите внимание, что мы используем **, чтобы распаковать словарь, тогда как со списками мы используем *, чтобы распаковать.
Кевин С.

213

Вы можете использовать наборы для получения объединенного списка уникальных значений

mergedlist = list(set(listone + listtwo))

45
Правда, однако, он также удалит дубликаты, если это то, что вас интересует. Добавление списка не будет этого делать.
метасарный

1
Как это сделать и сохранить информацию о заказе?
Натим

11
Лучше, чемlistone + [x for x in listtwo if x not in listone]
Натим

8
+1 ИМХО это правильный способ «объединения» (объединения) списков, в то время как «одобренный» ответ описывает, как объединять / добавлять списки (мультимножество)
alfasin

2
Если вы заботитесь о поддержании порядка ввода, то import collections; mergedlist = list(collections.OrderedDict.fromkeys(listone + listtwo))добьетесь цели.
СетМортон

186

Вы также можете использовать list.extend()метод для добавления a listв конец другого:

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

listone.extend(listtwo)

Если вы хотите сохранить исходный список без изменений, вы можете создать новый listобъект, и extendоба списка к нему:

mergedlist = []
mergedlist.extend(listone)
mergedlist.extend(listtwo)

82

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

Начиная с версии 3.7, это самые популярные методы stdlib для объединения двух (или более) списков в python.

введите описание изображения здесь

Сноски

  1. Это ловкое решение из-за его краткости. Но sumвыполняет конкатенацию попарно, что означает, что это квадратичная операция, так как память должна быть выделена для каждого шага. НЕ ИСПОЛЬЗУЙТЕ, если ваши списки большие.

  2. Смотрите chain и chain.from_iterable из документов. Вам нужно будет import itertoolsсначала. Конкатенация линейна в памяти, поэтому она является лучшей с точки зрения производительности и совместимости версий. chain.from_iterableбыл введен в 2.6.

  3. Этот метод использует дополнительные обобщения распаковки (PEP 448) , но не может обобщать до N списков, если вы сами не распаковываете вручную.

  4. a += bи a.extend(b)более или менее эквивалентны для всех практических целей. +=при вызове по списку вызовет внутренне list.__iadd__, что расширяет первый список на второй.


Представление

Объединение двух списков 1

введите описание изображения здесь

Между этими методами нет большой разницы, но это имеет смысл, учитывая, что все они имеют одинаковый порядок сложности (линейный). Нет особой причины предпочитать одно другому, кроме как из-за стиля.

Конкатенация N-List

введите описание изображения здесь

Графики были созданы с использованием модуля perfplot . Код, для вашей справки.

1. Методы iadd( +=) и extendработают на месте, поэтому каждый раз перед тестированием необходимо генерировать копию. Чтобы быть справедливым, у всех методов есть шаг перед копированием для левого списка, который можно игнорировать.


Комментарии к другим решениям

  • НЕ ИСПОЛЬЗУЙТЕ МЕТОД DUNDER list.__add__напрямую, в любом виде, форме или форме. На самом деле, держитесь подальше от более сложных методов и используйте операторы и operatorфункции, для которых они предназначены. Python имеет тщательно продуманную семантику, которая сложнее, чем просто вызов dunder напрямую. Вот пример . Итак, подведем итог, a.__add__(b)=> ПЛОХО; a + b=> ХОРОШО.

  • Некоторые ответы здесь предлагают reduce(operator.add, [a, b])для парной конкатенации - это то же самое, что sum([a, b], [])только более многословно.

  • Любой метод, который использует set, удалит дубликаты и потеряет порядок. Используйте с осторожностью.

  • for i in b: a.append(i)более многословно и медленнее, чем a.extend(b)одиночный вызов функции и более идиоматично. appendмедленнее из-за семантики, с которой память выделяется и увеличивается для списков. Смотрите здесь для аналогичного обсуждения.

  • heapq.mergeбудет работать, но его вариант использования для объединения отсортированных списков в линейное время. Использование его в любой другой ситуации - это анти-паттерн.

  • yieldПолучение списка элементов из функции является приемлемым методом, но chainделает это быстрее и лучше (у него есть путь к коду в C, поэтому он быстрый).

  • operator.add(a, b)является приемлемым функциональным эквивалентом a + b. Это варианты использования в основном для динамической отправки метода. Иначе предпочитаю a + bчто короче и более читабельно, на мой взгляд . YMMV.


ответы на stackoverflow.com/q/36863404/125507 могли бы использовать perfplot участок ( в том числе решение Numba)
эндолиты

@endolith немного завален работой, но я посмотрю и посмотрю, смогу ли я скинуться. Тай.
cs95

Какой метод лучше, чем производительность, быстрее? пожалуйста скажи.
Ганешдешмух

@ganeshdeshmukh TL; DR - все они хороши, и то, что вы выбираете, в основном зависит от стиля. "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.«Решения, не указанные в моем ответе или критикуемые в« Комментариях », рекомендую не использовать.
cs95


51

Этот вопрос напрямую задает вопрос о соединении двух списков. Тем не менее, поиск довольно высок, даже если вы ищете способ объединения многих списков (включая случай, когда вы присоединяетесь к нулевым спискам).

Я думаю, что лучше всего использовать списочные выражения:

>>> a = [[1,2,3], [4,5,6], [7,8,9]]
>>> [x for xs in a for x in xs]
[1, 2, 3, 4, 5, 6, 7, 8, 9]

Вы также можете создавать генераторы:

>>> map(str, (x for xs in a for x in xs))
['1', '2', '3', '4', '5', '6', '7', '8', '9']

Старый ответ

Рассмотрим этот более общий подход:

a = [[1,2,3], [4,5,6], [7,8,9]]
reduce(lambda c, x: c + x, a, [])

Будет выводить:

[1, 2, 3, 4, 5, 6, 7, 8, 9]

Обратите внимание, это также работает правильно, когда aесть []или[[1,2,3]] .

Тем не менее, это может быть сделано более эффективно с itertools:

a = [[1,2,3], [4,5,6], [7,8,9]]
list(itertools.chain(*a))

Если вам не нужен list, а просто повторяется, опустите list().

Обновить

Альтернатива, предложенная Патриком Коллинзом в комментариях, также может сработать для вас:

sum(a, [])

3
Примечание по Python 3: reduceтеперь в functoolsналичии, поэтому сначала вам нужно его импортировать.
Димитрис Фасаракис Хиллиард

41

Вы можете просто использовать оператор +or +=следующим образом:

a = [1, 2, 3]
b = [4, 5, 6]

c = a + b

Или:

c = []
a = [1, 2, 3]
b = [4, 5, 6]

c += (a + b)

Кроме того, если вы хотите, чтобы значения в объединенном списке были уникальными, вы можете сделать следующее:

c = list(set(a + b))

Последняя часть может произвольно изменить порядок предметов. Если вы хотите сохранить порядок, на CPython 3.6+ вы можете это сделатьlist(dict.fromkeys(a + b))
Boris

27

Стоит отметить, что itertools.chainфункция принимает переменное количество аргументов:

>>> l1 = ['a']; l2 = ['b', 'c']; l3 = ['d', 'e', 'f']
>>> [i for i in itertools.chain(l1, l2)]
['a', 'b', 'c']
>>> [i for i in itertools.chain(l1, l2, l3)]
['a', 'b', 'c', 'd', 'e', 'f']

Если в качестве входных данных используется итерация (кортеж, список, генератор и т. Д.), from_iterableМожно использовать метод класса:

>>> il = [['a'], ['b', 'c'], ['d', 'e', 'f']]
>>> [i for i in itertools.chain.from_iterable(il)]
['a', 'b', 'c', 'd', 'e', 'f']

22

С Python 3.3+ вы можете использовать yield из :

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

def merge(l1, l2):
    yield from l1
    yield from l2

>>> list(merge(listone, listtwo))
[1, 2, 3, 4, 5, 6]

Или, если вы хотите поддерживать произвольное количество итераторов:

def merge(*iters):
    for it in iters:
        yield from it

>>> list(merge(listone, listtwo, 'abcd', [20, 21, 22]))
[1, 2, 3, 4, 5, 6, 'a', 'b', 'c', 'd', 20, 21, 22]

Вы можете использовать itertools.chain(что эквивалентно) вместо определения своей собственной функции.
Борис

18

Если вы хотите объединить два списка в отсортированном виде, вы можете использовать mergeфункцию из heapqбиблиотеки.

from heapq import merge

a = [1, 2, 4]
b = [2, 4, 6, 7]

print list(merge(a, b))

15

Если вы не можете использовать оператор плюс ( +), вы можете использовать operatorимпорт:

import operator

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

result = operator.add(listone, listtwo)
print(result)

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

Кроме того, вы также можете использовать функцию __add__ Dunder :

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

result = list.__add__(listone, listtwo)
print(result)

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

3
Захват Дандерса, как правило, не лучший подход. Если +со стола, используйте operator.add.
Димитрис Фасаракис Хиллиард

2
Почему оператор «плюс» будет недоступен?
cs01

2
Обычно это не так :), но если вы делаете конкатенацию списка с помощью функции map или хотите сохранить функцию add в переменной, вы не можете использовать +.
Jpihl

13

В качестве более общего способа для большего количества списков вы можете поместить их в список и использовать функцию itertools.chain.from_iterable()1, которая на основе этого ответа является лучшим способом выравнивания вложенного списка:

>>> l=[[1, 2, 3], [4, 5, 6], [7, 8, 9]]
>>> import itertools
>>> list(itertools.chain.from_iterable(l))
[1, 2, 3, 4, 5, 6, 7, 8, 9]

1. Обратите внимание, что chain.from_iterable()доступно в Python 2.6 и более поздних версиях. В других версиях используйте chain(*l).


10

Если вам нужно объединить два упорядоченных списка со сложными правилами сортировки, вам, возможно, придется свернуть его самостоятельно, как показано в следующем коде (используя простое правило сортировки для удобства чтения :-)).

list1 = [1,2,5]
list2 = [2,3,4]
newlist = []

while list1 and list2:
    if list1[0] == list2[0]:
        newlist.append(list1.pop(0))
        list2.pop(0)
    elif list1[0] < list2[0]:
        newlist.append(list1.pop(0))
    else:
        newlist.append(list2.pop(0))

if list1:
    newlist.extend(list1)
if list2:
    newlist.extend(list2)

assert(newlist == [1, 2, 3, 4, 5])

Или просто использовать heapq.merge.
cs95

7

Вы можете использовать append()метод, определенный для listобъектов:

mergedlist =[]
for elem in listone:
    mergedlist.append(elem)
for elem in listtwo:
    mergedlist.append(elem)

9
просто чтобы вы знали, что если вы это делаете на практике, это намного, намного медленнее, чем другие предложенные методы. см. stackoverflow.com/questions/17479361/…
Райан Хейнинг

7
list(set(listone) | set(listtwo))

Приведенный выше код не сохраняет порядок, удаляет дубликаты из каждого списка (но не из объединенного списка)


6

Как уже указывалось многими, itertools.chain()это путь, если нужно применить одинаковый режим к обоим спискам. В моем случае у меня был ярлык и флаг, которые отличались от одного списка к другому, поэтому мне нужно было что-то немного более сложное. Как выясняется, за кадром itertools.chain()просто делает следующее:

for it in iterables:
    for element in it:
        yield element

(см. https://docs.python.org/2/library/itertools.html ), поэтому я черпал вдохновение и написал что-то вроде этого:

for iterable, header, flag in ( (newList, 'New', ''), (modList, 'Modified', '-f')):
    print header + ':'
    for path in iterable:
        [...]
        command = 'cp -r' if os.path.isdir(srcPath) else 'cp'
        print >> SCRIPT , command, flag, srcPath, mergedDirPath
        [...]

Здесь необходимо понять, что списки - это просто частный случай итерации, которые являются объектами, подобными любым другим; и что for ... inциклы в python могут работать с переменными кортежей, поэтому можно легко зацикливать несколько переменных одновременно.


5

Используйте простое понимание списка:

joined_list = [item for list_ in [list_one, list_two] for item in list_]

Он обладает всеми преимуществами новейшего подхода использования дополнительных распаковывающих обобщений - т.е. вы можете объединить произвольное количество различных итераций (например, списков, кортежей, диапазонов и генераторов) таким образом - и он не ограничен Python 3.5 или новее ,


4

Действительно краткий способ объединить список списков

list_of_lists = [[1,2,3], [4,5,6], [7,8,9]]
reduce(list.__add__, list_of_lists)

что дает нам

[1, 2, 3, 4, 5, 6, 7, 8, 9]

Пожалуйста, не используйте list.__add__, используйте operator.addвместо этого. Это более многословный эквивалент, sum(list_of_lists, [])который так же плох. НЕ ИСПОЛЬЗУЙТЕ!
CS95

@ cs95 Вы можете объяснить, в чем проблема, используя список .__ add__
Акаш Сингх

Методы dunder являются «закрытыми методами» и, как правило, не должны использоваться напрямую (они вызываются другими функциями). Исключения есть obj.__class__и obj.__dict__.
cs95

3

В Python вы можете объединить два массива совместимых измерений с помощью этой команды

numpy.concatenate([a,b])

4
Вопрос не задает для NumPy.
CS95

2

Итак, есть два простых способа.

  1. Использование+ : создает новый список из предоставленных списков

Пример:

In [1]: a = [1, 2, 3]

In [2]: b = [4, 5, 6]

In [3]: a + b
Out[3]: [1, 2, 3, 4, 5, 6]

In [4]: %timeit a + b
10000000 loops, best of 3: 126 ns per loop
  1. Использование расширения : добавляет новый список к существующему списку. Это означает, что он не создает отдельный список.

Пример:

In [1]: a = [1, 2, 3]

In [2]: b = [4, 5, 6]

In [3]: %timeit a.extend(b)
10000000 loops, best of 3: 91.1 ns per loop

Таким образом, мы видим, что из двух самых популярных методов extendэффективен.


2
Что если мне нужно добавить несколько списков, например, a + b + c + d + e?
Tweakimp

2
@Tweakimp Посмотрите этот ответ, который имеет несколько вариантов (я рекомендую chain.from_iterable).
cs95

2

Есть несколько способов конкатенировать списки в Python.

l1 = [1,2,3,4]
l2 = [3,4,5,6]

 1. new_list = l1.copy()
    new_list = new_list.extend(l2)
 2. new_list = l1 + l2
 3. new_list = [*l1, *l2]

1
Не могли бы вы объяснить, какую новую информацию этот ответ предоставляет другим?
CS95

Есть несколько способов конкатенировать списки в Python - все они подробно описаны в других, гораздо более старых ответах. Какую новую информацию это дает ??
Томерикоо

-1
import itertools

A = list(zip([1,3,5,7,9],[2,4,6,8,10]))
B = [1,3,5,7,9]+[2,4,6,8,10]
C = list(set([1,3,5,7,9] + [2,4,6,8,10]))

D = [1,3,5,7,9]
D.append([2,4,6,8,10])

E = [1,3,5,7,9]
E.extend([2,4,6,8,10])

F = []
for a in itertools.chain([1,3,5,7,9], [2,4,6,8,10]):
    F.append(a)


print ("A: " + str(A))
print ("B: " + str(B))
print ("C: " + str(C))
print ("D: " + str(D))
print ("E: " + str(E))
print ("F: " + str(F))

Вывод:

A: [(1, 2), (3, 4), (5, 6), (7, 8), (9, 10)]
B: [1, 3, 5, 7, 9, 2, 4, 6, 8, 10]
C: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
D: [1, 3, 5, 7, 9, [2, 4, 6, 8, 10]]
E: [1, 3, 5, 7, 9, 2, 4, 6, 8, 10]
F: [1, 3, 5, 7, 9, 2, 4, 6, 8, 10]


-2
lst1 = [1,2]

lst2 = [3,4]

def list_combinationer(Bushisms, are_funny):

    for item in lst1:
        lst2.append(item)
        lst1n2 = sorted(lst2)
        print lst1n2

list_combinationer(lst1, lst2)

[1,2,3,4]

4
Ну, пожалуйста, сделайте некоторое объяснение
U10-Forward

Какой смысл аргументов функции, если вы используете глобальные имена внутри нее?
Томерикоо

-2

Вы можете следовать за кодом

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

for i in listone:
    listtwo.append(i)
print(listtwo)

[1,2,3,4,5,6]
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.