Как объединить два списка в Python? - PullRequest
2071 голосов
/ 12 ноября 2009

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

Пример:

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

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

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

Ответы [ 25 ]

16 голосов
/ 07 июля 2015

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

from heapq import merge

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

print list(merge(a, b))
13 голосов
/ 20 октября 2014

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

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]
11 голосов
/ 06 июля 2015

В качестве более общего способа для большего количества списков вы можете поместить их в список и использовать функцию 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).

9 голосов
/ 07 ноября 2013

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

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])
7 голосов
/ 01 июня 2019

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

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

enter image description here

Сноска

  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__, который расширяет первый список на второй.


Performance

Слияние двух списков 1

enter image description here

Объединение N-списков

enter image description here

Графики были созданы с использованием модуля 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.

6 голосов
/ 07 июля 2016
list(set(listone) | set(listtwo))

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

6 голосов
/ 16 июля 2013

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

mergedlist =[]
for elem in listone:
    mergedlist.append(elem)
for elem in listtwo:
    mergedlist.append(elem)
6 голосов
/ 02 ноября 2015

Как уже указывалось многими, 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 могут работать с переменными кортежей, поэтому можно легко зацикливать несколько переменных одновременно.

3 голосов
/ 04 августа 2018

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

numpy.concatenate([a,b])
3 голосов
/ 04 июня 2018

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

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

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...