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


1,470

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

Пример:

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

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

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

насчет если Listone был '[3,2,1]'? Изменится ли выход? 12 ноя. 092009-11-12 07:06:25

+32

Может найти ответ в любой ссылке или учебнике Python. Лично я не возражаю, но этот вопрос выглядит как заданный исключительно для репутации mining;) 08 фев. 142014-02-08 12:46:05

  0

«merge» как «создать одну мелкую копию», «глубокую копию» или «итерацию с»? (@Clergyman, это совсем не так) 12 сен. 142014-09-12 03:31:44

+1

Не эта операция называется * concatination *, а не * слияние *? Я всегда думал, что слияние означает объединение + сортировка. 08 ноя. 142014-11-08 02:33:08

+1

Вы хотите просто ** добавить **, или вы хотите ** объединить два списка в отсортированном порядке **? Какой результат вы ожидаете для [1,3,6] и [2,4,5]? Можем ли мы предположить, что оба подсписок уже отсортированы (как в вашем примере)? 12 сен. 152015-09-12 07:51:44

+1

@LenarHoyt Исправить. Слияние подразумевает как бы произвольное или реляционное упорядочение как минимум. 04 авг. 172017-08-04 23:08:24

2,477

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

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

mergedlist = listone + listtwo 

Выход:

>>> mergedlist 
[1,2,3,4,5,6] 
+58

делает ли это создание глубокой копии списка и добавляет listtwo? 19 апр. 122012-04-19 12:34:36

+88

@ Daniel создаст новый список с неглубокой копией элементов в первом списке, а затем мелкую копию элементов во втором списке. Используйте copy.deepcopy для получения глубоких копий списков. 19 апр. 122012-04-19 14:51:41

+130

еще одна полезная деталь здесь: 'listone + = listtwo' приводит к' listone == [1, 2, 3, 4, 5, 6] ' 29 янв. 142014-01-29 16:14:49

+10

@ br1ckb0t изменит, на что указывает данный список. Итак: 'list3 = listone'' listone + = listtwo' Изменен ли список3? 19 фев. 142014-02-19 05:01:13

  0

@MikeH Да, он меняет список3. 19 фев. 142014-02-19 18:11:50

+7

это изменение список3. Тем не менее, если это не проблема, более просто читайте, чтобы добавить два списка вместо создания нового. 20 фев. 142014-02-20 18:55:52

  0

ВНИМАНИЕ: я не знаю, является ли это спецификацией Python3, но в некоторых случаях (массив numpy) [1,2,3] + [4] дает [5,6,7] !!! 08 апр. 152015-04-08 18:27:39

+1

@Pygmalion Это не специфичный для Python3, а специфический для того, как массивы NumPy обрабатывают операторы. См. Ответ Дж. Ф. Себастьяна в ответе Роберта Россни для конкатенации массивов NumPy. 16 апр. 152015-04-16 11:42:16


51

Это довольно просто, я думаю, что это было даже показано в tutorial:

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

И это также работает, когда 'listone' и' listtwo' имеют различное количество элементов ;-) 09 сен. 172017-09-09 14:36:56


191

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

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

Это лучший способ, потому что он также работает с массивом numpy. 25 сен. 122012-09-25 09:37:51

+1

будет работать так же: mergedList = itertools.chain (listone, listtwo) для элемента в объединенном списке: 01 мар. 132013-03-01 00:55:23

+9

@ d.putto: доступ к отдельным элементам очень медленный для массивов numpy (для каждого доступа требуется преобразовать необработанную память с помощью C тип к объекту Python. Векторизованные операции, такие как 'np.dot()', работают непосредственно с типами C без обратной поездки на Python и, следовательно, быстро).Вы можете использовать 'merged = np.r_ [a, b]' для получения конкатенированного массива numpy. 30 апр. 142014-04-30 03:38:57


142

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

mergedlist = list(set(listone + listtwo)) 
+66

это потеряет информацию о заказе. 20 сен. 102010-09-20 08:45:54

+26

Правда, однако, он также удалит дубликаты, если это то, что вас интересует. Сложение списка также не сделало бы этого. 21 авг. 122012-08-21 00:28:28

  0

Каков способ сделать это и сохранить информацию для заказа? 29 янв. 132013-01-29 13:12:50

+7

Лучше, чем '' listone + [x для x в listtwo, если x не в listone] '' 29 янв. 132013-01-29 13:13:40

+1

Если у меня был список списков, таких как этот: '[[0, 5], [1, 10] , [0, 7], [3, 5]] ' Как бы вы объединили их, чтобы избежать дубликатов в ключе (первое значение в каждом под-списке), но если они дубликаты, в итоге получается сумма вторых значений? Как так: '[[0, 12], [1, 10], [3, 5]]' Спасибо 23 июл. 132013-07-23 12:24:46

  0

@jslvtr Это может быть стоит отдельный вопрос 17 авг. 132013-08-17 02:06:54

+6

+1 ИМХО это правильный путь к " merge "(объединение), в то время как« одобренный »ответ описывает, как комбинировать/добавлять списки (multiset) 27 апр. 142014-04-27 04:07:50

  0

Если вы заботитесь о сохранении порядка ввода, то« импортируйте коллекции; mergedlist = list (collections.OrderedDict.fromkeys (listone + listtwo)) 'будет делать трюк. 15 дек. 162016-12-15 20:11:24


82

Вы могли бы также использовать extend для того, чтобы добавить list добавить конец другой:

listone = [1,2,3] 
listtwo = [4,5,6] 
mergedlist = [] 
mergedlist.extend(listone) 
mergedlist.extend(listtwo) 
  0

@MatthewPurdon extend не займет ни одного элемента, он ожидает список. 15 окт. 142014-10-15 21:43:32

  0

Вы можете использовать только listone.extend (listtwo), но скоро это будет устаревшим 01 авг. 162016-08-01 16:42:22

+3

@SergeyIvanov нет, это не будет. 'list.extend' никуда не денется. 29 окт. 172017-10-29 10:53:58


17

стоит отметить, что функция 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'] 

31

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

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)) 

6

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

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

, так что вы знаете, если это то, что вы делаете на практике, это намного, гораздо медленнее, чем другие предлагаемые методы. см. http://stackoverflow.com/questions/17479361/iterating-vs-list-concatenation/17479468#17479468 16 июл. 132013-07-16 02:10:42


6

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

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]) 

15

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

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] 

10

Если вы не хотите или не можете использовать оператор плюс (+), вы можете использует __add__ функцию:

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

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

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

захват dunders, как правило, не самый лучший подход. Если '+' отключен от таблицы, используйте 'operator.add'. 04 июл. 172017-07-04 12:00:19

  0

Выглядит намного красивее, но я думаю, для этого вам понадобится '' import operator''. 13 июл. 172017-07-13 14:42:19


7

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

>>> 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() доступен в питоне => 2.6.In других вариантов использования chain(*l)


12

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

from heapq import merge 

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

print list(merge(a,b)) 
+1

Примечание: это предполагает, что 'a' и' b' уже отсортированы 17 мар. 172017-03-17 10:24:28


9

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

>>> a = [1, 2, 3, 4] 
>>> b = [1, 4, 6, 7] 
>>> c = a + b 
>>> c 
[1, 2, 3, 4, 1, 4, 6, 7] 

Если вы не хотите дублирования:

>>> a = [1, 2, 3, 4, 5, 6] 
>>> b = [5, 6, 7, 8] 
>>> c = list(set(a + b)) 
>>> c 
[1, 2, 3, 4, 5, 6, 7, 8] 

24

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

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().

Update

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

sum(a, []) 
+1

'sum (a, [])' работает только тогда, когда «a» - это список списков. 14 сен. 162016-09-14 07:16:46

+1

Замечание Python 3: 'reduce' теперь находится в' functools', поэтому вам нужно сначала его импортировать. 24 июл. 172017-07-24 18:00:52


5

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


64

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

Несмотря на то, что это старый ответ, еще одна альтернатива была введена через принятие PEP 448, который заслуживает упоминания.

ОПТООСЗ, под названием Дополнительной Распаковка Обобщение, как правило, уменьшаются некоторые синтаксические ограничениями при использовании * снимались выражения в Python; с ним, соединяя два списка (применяется к любому Iterable) теперь может также быть сделано с:

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

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

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

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


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

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


Миленькие дерзкий, что это также быстрее, чем другие подходы:

from itertools import chain 
# 4 lists of 1000 elements 
l1, l2, l3, l4 = [[*range(1000)] for _ in range(4)] 

# unpacking into [] 
%timeit [*l1, *l2, *l3, *l4] 
20 µs ± 18.6 ns per loop (mean ± std. dev. of 7 runs, 10000 loops each) 

# using +  
%timeit l1 + l2 + l3 + l4 
49.5 µs ± 90.6 ns per loop (mean ± std. dev. of 7 runs, 10000 loops each) 

# using itertools.chain 
%timeit list(chain(l1, l2, l3, l4)) 
50.4 µs ± 12 ns per loop (mean ± std. dev. of 7 runs, 10000 loops each) 

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

  0

это: 'lst = [1,2,3, * [4,5,6]]' said 'Ожидаемое:]' 04 ноя. 162016-11-04 13:43:40

+1

@ Mahesha999, похоже, не может проверить, что он работает так, как ожидалось для меня. 04 ноя. 162016-11-04 19:57:25


6
list(set(listone) | set(listtwo)) 

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


3
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] 

1

Если вы хотите новый список в то время как сохранение двух старых списков:

joinedList = [] 
for i in listOne: 
    joinedList.append(i) 
for j in listTwo: 
    joinedList.append(j) 

sorted(joinedList) 

return joinedList 
+2

Поскольку вы 'return'ing, это должно быть в функции. (Так как это запрещено вне функции) 04 июл. 172017-07-04 12:02:01


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] 

4

Вы можете пойти на extend функции.

l1 = [1,2,3] 
l2 = [4,5,6] 
l1.extend(l2) 
print l1 

выход: [1,2,3,4,5,6]