Jak połączyć dwie listy w Pythonie?

2526

Jak połączyć dwie listy w Pythonie?

Przykład:

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

Spodziewany rezultat:

>>> joinedlist
[1, 2, 3, 4, 5, 6]
y2k
źródło
6
Czy chcesz po prostu dołączyć , czy chcesz scalić dwie listy w posortowanej kolejności ? Jakiej wydajności oczekujesz dla [1,3,6] i [2,4,5]? Czy możemy założyć, że obie listy podrzędne są już posortowane (jak w twoim przykładzie)?
smci
1
... także co jeśli listy mają duplikaty np. [1,2,5] and [2,4,5,6]? Czy chcesz, aby duplikaty zostały uwzględnione, wykluczone czy nieistotne?
smci

Odpowiedzi:

3900

Możesz użyć +operatora, aby je połączyć:

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

joinedlist = listone + listtwo

Wynik:

>>> joinedlist
[1,2,3,4,5,6]
Daniel G.
źródło
110
czy to tworzy głęboką kopię listone i dołącza listtwo?
Daniel F
152
@Daniel utworzy nową listę z płytką kopią przedmiotów na pierwszej liście, a następnie płytką kopią przedmiotów na drugiej liście. Użyj copy.deepcopy, aby uzyskać głębokie kopie list.
Daniel G
219
kolejny użyteczny szczegół tutaj: listone += listtwowynikilistone == [1, 2, 3, 4, 5, 6]
rickcnagy
16
@ br1ckb0t to zmieni to, na który listone wskazuje? Więc: list3 = listone listone+=listtwo Czy zmieniła się również lista 3?
MikeH
11
zmienia listę 3. Jeśli jednak nie stanowi to problemu, łatwiej jest dodać dwie listy zamiast tworzyć nową.
rickcnagy
316

Możliwe jest również utworzenie generatora, który po prostu iteruje elementy na obu listach za pomocą itertools.chain(). Umożliwia to łączenie list (lub dowolnej iterowalnej) razem w celu przetworzenia bez kopiowania elementów na nową listę:

import itertools
for item in itertools.chain(listone, listtwo):
    # Do something with each list item
Robert Rossney
źródło
4
chainjest wolniejszy (ale niewiele) dla dwóch list, ale jest najszybszym rozwiązaniem do łączenia wielu list (n >> 2).
cs95
@ cs95 powoli w porównaniu do czego?
Moberg
@Moberg W porównaniu z innymi sposobami łączenia list, w celach informacyjnych zapoznaj się z moimi punktami odniesienia tutaj .
cs95
262

>= 3.5Alternatywa dla Pythona :[*l1, *l2]

Wprowadzono kolejną alternatywę, której akceptacja PEP 448zasługuje na wzmiankę.

PEP, zatytułowany Dodatkowe uogólnienia rozpakowywania , ogólnie zmniejszył pewne ograniczenia składniowe podczas używania *wyrażenia oznaczonego gwiazdką w Pythonie; dzięki niemu łączenie dwóch list (dotyczy dowolnej iterowalnej) można teraz również wykonać za pomocą:

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

Ta funkcjonalność została zdefiniowana dla Pythona3.5 i nie została przeniesiona do poprzednich wersji w 3.xrodzinie. W nieobsługiwanych wersjach pojawi SyntaxErrorsię a.

Podobnie jak w przypadku innych podejść, to również tworzy płytką kopię elementów na odpowiednich listach.


Upside do tego podejścia jest to, że naprawdę nie trzeba list w celu jej wykonania, wszystko, co jest iterable zrobi. Jak stwierdzono w PEP:

Jest to również przydatne jako bardziej czytelny sposób sumowania iteracji na liście, taki jak ten, my_list + list(my_tuple) + list(my_range)który jest teraz równoważny z just [*my_list, *my_tuple, *my_range].

A więc dodanie z +spowoduje podniesienie TypeErrorniedopasowania typu:

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

Następujące nie będą:

res = [*l, *r]

ponieważ najpierw rozpakuje zawartość iterable, a następnie po prostu utworzy plik listz zawartości.

Dimitris Fasarakis Hilliard
źródło
1
Dobrym przykładem metody rozpakowywania działającej na typach iterowalnych są funkcje, które zwracają iterator na jednej z list, które łączysz. Na przykład, można odwrócić jedną z list jesteś złączenie: res = [*l1, *reversed(l2)]. Ponieważ reversedzwraca iterator, res = l1 + reversed(l2)zgłosiłby błąd.
alan
2
Warto zauważyć, że jest to analogiczne do łączenia słowników w pythonie. dict3 = {** dict1, ** dict2}. Zauważ, że używamy ** do rozpakowywania słownika, natomiast w przypadku list używamy * do rozpakowywania.
Kevin S,
212

Możesz użyć zestawów, aby uzyskać scaloną listę unikalnych wartości

mergedlist = list(set(listone + listtwo))
Radagast
źródło
45
To prawda, że ​​usunie także duplikaty, jeśli jesteś tym zainteresowany. Dodanie listy nie spowoduje tego.
metasoarous
1
Jak to zrobić i zachować informacje o zamówieniu?
Natim
11
Lepiej niżlistone + [x for x in listtwo if x not in listone]
Natim
8
+1 IMHO to poprawny sposób „scalania” (unii) list, podczas gdy „zatwierdzona” odpowiedź opisuje, jak łączyć / dodawać listy (multiset)
alfasin
2
Jeśli zależy ci na utrzymaniu porządku wprowadzania, import collections; mergedlist = list(collections.OrderedDict.fromkeys(listone + listtwo))zrobi to samo.
SethMMorton,
185

Możesz także użyć tej list.extend()metody, aby dodać listna końcu innego:

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

listone.extend(listtwo)

Jeśli chcesz zachować nienaruszoną oryginalną listę, możesz utworzyć nowy listobiekt i extendobie listy:

mergedlist = []
mergedlist.extend(listone)
mergedlist.extend(listtwo)
Gourneau
źródło
80

Jak połączyć dwie listy w Pythonie?

Od wersji 3.7 są to najpopularniejsze metody stdlib do łączenia dwóch (lub więcej) list w pythonie.

wprowadź opis zdjęcia tutaj

Przypisy

  1. Jest to zręczne rozwiązanie ze względu na jego zwięzłość. Ale sumdokonuje konkatenacji w parach, co oznacza, że ​​jest to operacja kwadratowa, ponieważ pamięć musi być przydzielona dla każdego kroku. NIE UŻYWAJ, jeśli twoje listy są duże.

  2. Zobacz chain i chain.from_iterable z dokumentów. import itertoolsNajpierw musisz . Łączenie jest liniowe w pamięci, więc jest to najlepsze pod względem wydajności i kompatybilności wersji. chain.from_iterablezostał wprowadzony w wersji 2.6.

  3. Ta metoda wykorzystuje dodatkowe uogólnienia rozpakowywania (PEP 448) , ale nie może uogólniać na listy N, chyba że ręcznie rozpakujesz każdą z nich samodzielnie.

  4. a += bi a.extend(b)są mniej więcej równoważne dla wszystkich praktycznych celów. +=gdy zostanie wywołany na liście, zadzwoni wewnętrznie list.__iadd__, co wydłuży pierwszą listę o drugą.


Wydajność

Łączenie 2 list 1

wprowadź opis zdjęcia tutaj

Nie ma dużej różnicy między tymi metodami, ale ma to sens, biorąc pod uwagę, że wszystkie mają ten sam rząd złożoności (liniowy). Nie ma żadnego szczególnego powodu, aby preferować jeden od drugiego, z wyjątkiem stylu.

Łączenie N-list

wprowadź opis zdjęcia tutaj

Wykresy zostały wygenerowane przy użyciu modułu perfplot . Kod, w celach informacyjnych.

1. iadd( +=) i extendmetody działają na miejscu, więc kopia musi być generowana za każdym razem przed testowaniem. Aby zachować uczciwość, wszystkie metody mają krok poprzedzający skopiowanie listy po lewej stronie, którą można zignorować.


Komentarze do innych rozwiązań

  • NIE UŻYWAJ METODY DUNDERA list.__add__bezpośrednio w jakikolwiek sposób, kształcie lub formie. W rzeczywistości trzymaj się z daleka od metod dundera i używaj operatorów i operatorfunkcji tak, jak zostały zaprojektowane. Python ma staranną semantykę, która jest bardziej skomplikowana niż tylko bezpośrednie wywołanie dundera. Oto przykład . Podsumowując: a.__add__(b)=> ZŁE; a + b=> DOBRY.

  • Niektóre odpowiedzi tutaj oferują reduce(operator.add, [a, b])konkatenację parami - to samo, co sum([a, b], [])tylko bardziej nieporadne.

  • Każda zastosowana metoda setspowoduje usunięcie duplikatów i utratę zamówienia. Używaj ostrożnie.

  • for i in b: a.append(i)jest bardziej pracochłonny i wolniejszy niż a.extend(b), który jest wywołaniem jednofunkcyjnym i bardziej idiomatyczny. appendjest wolniejszy ze względu na semantykę, z jaką pamięć jest przydzielana i powiększana dla list. Zobacz tutaj podobną dyskusję.

  • heapq.mergebędzie działać, ale jego przykładem użycia jest scalanie posortowanych list w czasie liniowym. Używanie go w każdej innej sytuacji jest anty-wzorem.

  • yieldWpisywanie elementów listy z funkcji jest akceptowalną metodą, ale chainrobi to szybciej i lepiej (ma ścieżkę kodu w C, więc jest szybka).

  • operator.add(a, b)jest akceptowalnym funkcjonalnym odpowiednikiem a + b. Jego przypadki użycia są głównie do dynamicznej wysyłki metod. W przeciwnym razie, moim zdaniem , wolę ten, a + bktóry jest krótszy i bardziej czytelny . YMMV.

cs95
źródło
odpowiedzi na stackoverflow.com/q/36863404/125507 mogłyby użyć wykresu perfplot (w tym rozwiązania numba)
endolith
@endolith trochę zalany pracą, ale przyjrzę się i zobaczę, czy dam radę. Ty.
cs95,
która metoda jest lepsza od wydajności, szybsza? Proszę powiedzieć.
ganeshdeshmukh
@ganeshdeshmukh TL; DR jest taki, że wszystkie są dobre, a wybór jednego zależy głównie od stylu. "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.„Rozwiązań niewymienionych w mojej odpowiedzi lub krytykowanych w„ Komentarze ”Polecam nie używać.
cs95
78

Jest to dość proste i myślę, że zostało nawet pokazane w samouczku :

>>> listone = [1,2,3]
>>> listtwo = [4,5,6]
>>>
>>> listone + listtwo
[1, 2, 3, 4, 5, 6]
Tuure Laurinolli
źródło
51

To pytanie dotyczy bezpośrednio połączenia dwóch list. Jednak jest dość wysoki w wyszukiwaniu, nawet jeśli szukasz sposobu dołączenia do wielu list (w tym przypadku, gdy dołączasz do list zerowych).

Myślę, że najlepszą opcją jest użycie wyrażeń listowych:

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

Możesz także tworzyć generatory:

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

Stara odpowiedź

Rozważ to bardziej ogólne podejście:

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

Wyjdzie:

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

Uwaga, działa to również poprawnie, gdy ajest []lub [[1,2,3]].

Można to jednak zrobić bardziej efektywnie za pomocą itertools:

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

Jeśli nie potrzebujesz list, ale tylko iterowalnego, pomiń list().

Aktualizacja

Alternatywa zaproponowana przez Patricka Collinsa w komentarzach może również działać dla Ciebie:

sum(a, [])
wonder.mice
źródło
3
Uwaga do Python 3: reducejest już dostępna, functoolswięc najpierw musisz ją zaimportować.
Dimitris Fasarakis Hilliard
41

Możesz po prostu użyć operatora +lub +=w następujący sposób:

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

c = a + b

Lub:

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

c += (a + b)

Ponadto, jeśli chcesz, aby wartości na scalonej liście były unikalne, możesz:

c = list(set(a + b))
Mit
źródło
Ostatnia część może dowolnie ponownie zamówić przedmioty. Jeśli chcesz zachować porządek, na CPython 3.6+ możesz to zrobićlist(dict.fromkeys(a + b))
Boris
27

Warto zauważyć, że itertools.chainfunkcja przyjmuje zmienną liczbę argumentów:

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

Jeśli wejściowy jest iterowalny (krotka, lista, generator itp.), from_iterableMożna zastosować metodę klasy:

>>> il = [['a'], ['b', 'c'], ['d', 'e', 'f']]
>>> [i for i in itertools.chain.from_iterable(il)]
['a', 'b', 'c', 'd', 'e', 'f']
Dariusz Walczak
źródło
22

W Pythonie 3.3+ możesz korzystać z zysków z :

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]

Lub jeśli chcesz wesprzeć dowolną liczbę iteratorów:

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]

źródło
Możesz użyć itertools.chain(co jest równoważne) zamiast definiować własną funkcję.
Boris
18

Jeśli chcesz scalić dwie listy w posortowanej formie, możesz użyć mergefunkcji z heapqbiblioteki.

from heapq import merge

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

print list(merge(a, b))
lavee_singh
źródło
15

Jeśli nie możesz użyć operatora plus ( +), możesz użyć operatorimportu:

import operator

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

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

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

Alternatywnie możesz również użyć funkcji __add__ dunder :

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

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

>>> [1, 2, 3, 4, 5, 6]
jpihl
źródło
3
chwytanie dunderów nie jest na ogół najlepszym podejściem. Jeśli +jest poza stołem, użyj operator.add.
Dimitris Fasarakis Hilliard
2
Dlaczego operator plus byłby niedostępny?
cs01
2
Zwykle nie byłoby :), ale jeśli wykonujesz konkatenację listy z funkcją map lub chcesz zapisać funkcję dodawania w zmiennej, nie możesz użyć +.
jpihl
13

Jako ogólniejszy sposób dla większej liczby list możesz umieścić je w liście i użyć funkcji itertools.chain.from_iterable()1, która na podstawie tej odpowiedzi jest najlepszym sposobem na spłaszczenie zagnieżdżonej listy:

>>> 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. Zauważ, że chain.from_iterable()jest dostępny w Pythonie 2.6 i nowszych. W innych wersjach użyj chain(*l).

Kasramvd
źródło
10

Jeśli potrzebujesz scalić dwie uporządkowane listy ze skomplikowanymi regułami sortowania, być może będziesz musiał rzucić je samodzielnie, jak w poniższym kodzie (używając prostej reguły sortowania dla czytelności :-)).

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])
Pan Shark
źródło
Lub po prostu użyj heapq.merge.
cs95
7

Możesz użyć append()metody zdefiniowanej na listobiektach:

mergedlist =[]
for elem in listone:
    mergedlist.append(elem)
for elem in listtwo:
    mergedlist.append(elem)
mingxiao
źródło
9
po prostu wiesz, że jeśli robisz to w praktyce, jest to znacznie, dużo wolniej niż inne proponowane metody. patrz stackoverflow.com/questions/17479361/…
Ryan Haining 16'13
7
list(set(listone) | set(listtwo))

Powyższy kod nie zachowuje kolejności, usuwa duplikaty z każdej listy (ale nie z listy konkatenowanej)

SuperNova
źródło
6

Jak już zauważyło wielu, itertools.chain()jest to droga, jeśli trzeba zastosować dokładnie to samo traktowanie do obu list. W moim przypadku miałem etykietę i flagę, które różniły się od jednej listy do drugiej, więc potrzebowałem czegoś nieco bardziej złożonego. Jak się okazuje, za kulisami itertools.chain()po prostu wykonuje następujące czynności:

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

(patrz https://docs.python.org/2/library/itertools.html ), więc zaczerpnąłem inspirację z tego miejsca i napisałem coś w tym stylu:

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
        [...]

Główne punkty do zrozumienia tutaj to, że listy są tylko specjalnym przypadkiem iteracji, które są obiektami jak każdy inny; i że for ... inpętle w pythonie mogą współpracować ze zmiennymi krotkowymi, więc łatwo jest zapętlić wiele zmiennych jednocześnie.

Francesco Marchetti-Stasi
źródło
5

Użyj prostego zrozumienia listy:

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

Ma wszystkie zalety najnowszego podejścia polegającego na stosowaniu dodatkowych uogólnień rozpakowywania - tzn. Można w ten sposób połączyć dowolną liczbę różnych iteracji (na przykład list, krotek, zakresów i generatorów) - i nie ogranicza się to do Pythona 3.5 lub nowszego .

z33k
źródło
4

Naprawdę zwięzłym sposobem na połączenie listy list jest

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

co daje nam

[1, 2, 3, 4, 5, 6, 7, 8, 9]
Akash Singh
źródło
Proszę nie używać list.__add__, użyj operator.addzamiast. Jest to bardziej niewygodny odpowiednik, sum(list_of_lists, [])który jest równie zły. NIE UŻYWAJ!
cs95
@ cs95 czy możesz wyjaśnić, na czym polega problem, używając listy .__ add__
Akash Singh
metody dundera są „metodami prywatnymi” i zwykle nie powinny być używane bezpośrednio (są wywoływane przez inne funkcje). Wyjątkami są obj.__class__i obj.__dict__.
cs95
3

W Pythonie za pomocą tego polecenia można połączyć dwie tablice zgodnych wymiarów

numpy.concatenate([a,b])
Michael Grossmann
źródło
4
Pytanie nie wymaga numpy.
cs95
2

Są więc dwa proste sposoby.

  1. Używanie+ : Tworzy nową listę na podstawie dostarczonych list

Przykład:

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. Korzystanie z rozszerzenia : dołącza nową listę do istniejącej listy. Oznacza to, że nie tworzy osobnej listy.

Przykład:

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

Widzimy zatem, że jedna z dwóch najpopularniejszych metod extendjest wydajna.

Vishvajit Pathak
źródło
2
Co jeśli muszę dodać wiele list, np. A + b + c + d + e?
Tweakimp,
2
@Tweakimp Zobacz tę odpowiedź, która ma kilka opcji (polecam chain.from_iterable).
cs95
2

Istnieje wiele sposobów konkatenetowania list w pythonie.

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

1. new_list = l1.extend(l2)
2. new_list = l1 + l2
3. new_list = [*l1, *l2]
chatrapathi
źródło
1
Czy możesz wyjaśnić, jakie nowe informacje zawiera ta odpowiedź w stosunku do innych?
cs95
Istnieje wiele sposobów konkatenetowania list w pythonie - które są szczegółowo omówione w innych, znacznie starszych odpowiedziach. Jakie nowe informacje to zapewnia?
Tomerikoo
-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))

Wynik:

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]
JamesVeug
źródło
-1

Jeśli chcesz nową listę, zachowując dwie stare listy:

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

    sorted(joinedList)

    return joinedList
Ukendar Vadivel
źródło
Czym to się różni od tej odpowiedzi autorstwa mingxiao?
Tomerikoo
-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]
James Miller
źródło
4
Cóż, proszę o wyjaśnienie
U10-Forward
Jaki jest sens argumentów funkcji, jeśli używasz w niej globalnych nazw?
Tomerikoo
-2

Możesz postępować zgodnie z kodem

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

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

[1,2,3,4,5,6]
piękny islam
źródło