Come concatenare due elenchi in Python?


2531

Come concatenare due elenchi in Python?

Esempio:

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

Risultato previsto:

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

6
Vuoi semplicemente aggiungere o vuoi unire le due liste in ordine ? Quale output ti aspetti per [1,3,6] e [2,4,5]? Possiamo presumere che entrambe le liste siano già ordinate (come nel tuo esempio)?
smci,

1
... e anche se gli elenchi hanno duplicati, ad esempio [1,2,5] and [2,4,5,6]? Vuoi che i duplicati siano inclusi, esclusi o che non ti interessino?
smci,

Risposte:


3905

È possibile utilizzare l' +operatore per combinarli:

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

joinedlist = listone + listtwo

Produzione:

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

110
questo crea una copia profonda di listone e aggiunge listtwo?
Daniel F

152
@Daniel creerà un nuovo elenco con una copia superficiale degli elementi nel primo elenco, seguita da una copia superficiale degli elementi nel secondo elenco. Utilizzare copy.deepcopy per ottenere copie complete degli elenchi.
Daniel G

219
un altro dettaglio utile qui: listone += listtworisultati inlistone == [1, 2, 3, 4, 5, 6]
rickcnagy

16
@ br1ckb0t cambierà ciò a cui punta il listone? Quindi: anche list3 = listone listone+=listtwo List3 è cambiato?
MikeH,

11
cambia list3. Tuttavia, se questo non è un problema, è più semplice da leggere aggiungendo le due liste invece di crearne una nuova.
rickcnagy,

319

È anche possibile creare un generatore che scorre semplicemente sugli elementi in entrambi gli elenchi utilizzando itertools.chain(). Ciò consente di raggruppare gli elenchi (o qualsiasi iterabile) insieme per l'elaborazione senza copiare gli elementi in un nuovo elenco:

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

4
chainè più lento (ma non di molto) per due elenchi, ma è la soluzione più veloce per concatenare più elenchi (n >> 2).
cs95,

@ cs95 lento rispetto a cosa?
Moberg,

@Moberg Rispetto ad altri modi di concatenare elenchi, per riferimento vedere i miei benchmark qui .
cs95,

265

>= 3.5Alternativa a Python :[*l1, *l2]

Un'altra alternativa è stata introdotta attraverso l'accettazione di PEP 448cui merita menzione.

Il PEP, intitolato General Unpacking Generalizations , generalmente riduceva alcune restrizioni sintattiche quando si utilizzava l' *espressione stellata in Python; con esso, unendo due elenchi (vale per qualsiasi iterabile) ora può essere fatto anche con:

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

Questa funzionalità è stata definita per Python e3.5 non è stata trasferita alle versioni precedenti della 3.xfamiglia. Nelle versioni non supportate SyntaxErrorverrà generato a.

Come con gli altri approcci, anche questo crea una copia superficiale degli elementi negli elenchi corrispondenti.


L' aspetto positivo di questo approccio è che non hai davvero bisogno di elenchi per eseguirlo, tutto ciò che è iterabile lo farà. Come indicato nel PEP:

Questo è utile anche come un modo più leggibile di sommare gli iterabili in un elenco, come ad esempio my_list + list(my_tuple) + list(my_range)che ora è equivalente a just [*my_list, *my_tuple, *my_range].

Quindi, mentre l'aggiunta con +aumenterebbe a TypeErrorcausa della mancata corrispondenza del tipo:

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

Quanto segue non lo farà:

res = [*l, *r]

perché prima disimballerà il contenuto degli iterabili e poi semplicemente creerà un listcontenuto.


1
Un bell'esempio dell'approccio di decompressione che lavora su tipi iterabili sono le funzioni che restituiscono un iteratore su una delle liste che stai concatenando. Ad esempio, è possibile invertire una delle liste che stai concatenare: res = [*l1, *reversed(l2)]. Poiché reversedrestituisce un iteratore, res = l1 + reversed(l2)genererebbe un errore.
alan

2
Vale la pena notare che questo è analogo alla combinazione dei dizionari in Python. dict3 = {** dict1, ** dict2}. Si noti che utilizziamo ** per decomprimere il dizionario mentre con gli elenchi utilizziamo * per decomprimere.
Kevin S,

213

È possibile utilizzare i set per ottenere un elenco unito di valori univoci

mergedlist = list(set(listone + listtwo))

45
È vero, tuttavia, rimuoverà anche i duplicati, se è quello che ti interessa. L'aggiunta dell'elenco insieme non lo farebbe.
metasoario

1
Qual è il modo per farlo e conservare le informazioni di ordinazione?
Natim

11
Meglio dilistone + [x for x in listtwo if x not in listone]
Natim,

8
+1 IMHO questo è il modo corretto di "unire" elenchi (unione) mentre la risposta "approvata" descrive come combinare / aggiungere elenchi (multiset)
alfasin

2
Se ti interessa mantenere l'ordine di input, allora import collections; mergedlist = list(collections.OrderedDict.fromkeys(listone + listtwo))farà il trucco.
SethMMorton,

186

Puoi anche usare il list.extend() metodo per aggiungere lista alla fine di un altro:

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

listone.extend(listtwo)

Se si desidera mantenere intatto l'elenco originale, è possibile creare un nuovo listoggetto ed extendentrambi gli elenchi:

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

82

Come concatenare due elenchi in Python?

A partire da 3.7, questi sono i metodi stdlib più popolari per concatenare due (o più) liste in Python.

inserisci qui la descrizione dell'immagine

Le note

  1. Questa è una soluzione brillante per la sua succinta. Ma sumesegue la concatenazione in modo a coppie, il che significa che si tratta di un'operazione quadratica in quanto la memoria deve essere allocata per ogni passaggio. NON USARE se le tue liste sono grandi.

  2. Vedi chain e chain.from_iterable dai documenti. Dovrai import itertoolsprima. La concatenazione è lineare nella memoria, quindi è la migliore in termini di prestazioni e compatibilità delle versioni. chain.from_iterableè stato introdotto in 2.6.

  3. Questo metodo utilizza generalizzazioni di decompressione aggiuntive (PEP 448) , ma non può generalizzare a N elenchi a meno che non si decomprimano manualmente ciascuno di essi.

  4. a += be a.extend(b)sono più o meno equivalenti per tutti gli scopi pratici. +=quando chiamato su un elenco chiamerà internamente list.__iadd__, il che estende il primo elenco di secondo.


Prestazione

Concatenazione in 2 elenchi 1

inserisci qui la descrizione dell'immagine

Non c'è molta differenza tra questi metodi, ma ha senso dato che hanno tutti lo stesso ordine di complessità (lineare). Non vi è alcun motivo particolare per preferire l'una all'altra se non per una questione di stile.

Concatenazione N-List

inserisci qui la descrizione dell'immagine

I grafici sono stati generati utilizzando il modulo perfplot . Codice, per riferimento.

1. Il iadd( +=) e i extendmetodi funzionano sul posto, quindi una copia deve essere generata ogni volta prima del test. Per mantenere le cose giuste, tutti i metodi hanno un passaggio pre-copia per l'elenco a sinistra che può essere ignorato.


Commenti su altre soluzioni

  • NON UTILIZZARE IL METODO DUNDER list.__add__direttamente in alcun modo, forma o forma. In effetti, stai alla larga dai metodi del dunder e usa gli operatori e le operatorfunzioni per cui sono stati progettati. Python ha un'attenta semantica inserita in questi che sono più complicati del semplice chiamare direttamente il dunder. Ecco un esempio . Quindi, per riassumere, a.__add__(b)=> BAD; a + b=> BUONO.

  • Alcune risposte qui offrono reduce(operator.add, [a, b])una concatenazione a coppie - questo è lo stesso di sum([a, b], [])solo più prolisso.

  • Qualsiasi metodo che utilizza seteliminerà i duplicati e perderà l'ordinamento. Usare con cautela.

  • for i in b: a.append(i)è più prolisso e più lento di a.extend(b), che è una chiamata a funzione singola e più idiomatica. appendè più lento a causa della semantica con cui la memoria viene allocata e cresciuta per gli elenchi. Vedi qui per una discussione simile.

  • heapq.mergefunzionerà, ma il suo caso d'uso è per unire gli elenchi ordinati in tempo lineare. Usarlo in qualsiasi altra situazione è un anti-schema.

  • yieldL'elenco di elementi da una funzione è un metodo accettabile, ma lo chainfa più velocemente e meglio (ha un percorso di codice in C, quindi è veloce).

  • operator.add(a, b)è un equivalente funzionale accettabile di a + b. I suoi casi d'uso sono principalmente per l'invio di metodi dinamici. Altrimenti, preferisco a + bche sia più breve e più leggibile, secondo me . YMMV.


le risposte a stackoverflow.com/q/36863404/125507 potrebbero usare una trama perfplot (compresa la soluzione numba)
endolith

@endolith ha invaso un po 'di lavoro, ma darò un'occhiata e vedrò se riesco a entrare. Ty.
cs95,

qual è il metodo migliore allora più saggio, più veloce? per favore dillo.
Ganeshdeshmukh,

@ganeshdeshmukh I TL; DR sono tutti buoni e quale scegli è principalmente una questione di stile. "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."Soluzioni non elencate nella mia risposta o criticate in" Commenti "Consiglio di non utilizzare.
cs95

78

Questo è abbastanza semplice e penso che sia stato mostrato anche nel tutorial :

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

51

Questa domanda si pone direttamente sull'unione di due elenchi. Tuttavia, la ricerca è piuttosto elevata anche quando stai cercando un modo per unirti a molte liste (incluso il caso in cui ti unisci a zero liste).

Penso che l'opzione migliore sia quella di utilizzare la comprensione dell'elenco:

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

Puoi anche creare generatori:

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

Vecchia risposta

Considera questo approccio più generico:

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

Uscita:

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

Nota, questo funziona anche correttamente quando aè []o[[1,2,3]] .

Tuttavia, questo può essere fatto in modo più efficiente con itertools:

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

Se non hai bisogno di un list, ma solo un iterabile, ometti list().

Aggiornare

Un'alternativa suggerita da Patrick Collins nei commenti potrebbe funzionare anche per te:

sum(a, [])

3
Nota per Python 3: reduceè ora disponibile, functoolsquindi devi prima importarlo.
Dimitris Fasarakis Hilliard,

41

Puoi semplicemente usare l' operatore +o +=come segue:

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

c = a + b

O:

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

c += (a + b)

Inoltre, se desideri che i valori nell'elenco unito siano univoci, puoi fare:

c = list(set(a + b))

L'ultima parte può riordinare arbitrariamente gli articoli. Se vuoi conservare l'ordine, su CPython 3.6+ puoi farlolist(dict.fromkeys(a + b))
Boris,

27

Vale la pena notare che la itertools.chainfunzione accetta un numero variabile di argomenti:

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

Se è un input iterabile (tupla, elenco, generatore, ecc.), from_iterableÈ possibile utilizzare il metodo class:

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

22

Con Python 3.3+ puoi usare la resa di :

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]

Oppure, se si desidera supportare un numero arbitrario di iteratori:

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]

Puoi usare itertools.chain(che è equivalente) invece di definire la tua funzione.
Boris,

18

Se si desidera unire i due elenchi in forma ordinata, è possibile utilizzare la mergefunzione dalla heapqlibreria.

from heapq import merge

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

print list(merge(a, b))

15

Se non puoi utilizzare l'operatore più ( +), puoi utilizzare l' operatorimportazione:

import operator

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

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

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

In alternativa, puoi anche usare la funzione __add__ dunder :

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

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

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

3
afferrare i dunders non è generalmente l'approccio migliore. Se +è fuori dal tavolo, utilizzare operator.add.
Dimitris Fasarakis Hilliard

2
Perché l'operatore plus non sarebbe disponibile?
CS01,

2
Normalmente non lo è :) ma se si sta eseguendo la concatenazione di elenchi con la funzione map o si desidera memorizzare la funzione add in una variabile, non è possibile utilizzare +.
jpihl,

13

Come modo più generale per più elenchi è possibile inserirli in un elenco e utilizzare la funzione itertools.chain.from_iterable()1 che in base a questa risposta è il modo migliore per appiattire un elenco nidificato:

>>> 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. Nota che chain.from_iterable()è disponibile in Python 2.6 e versioni successive. In altre versioni, utilizzare chain(*l).


10

Se devi unire due elenchi ordinati con regole di ordinamento complicate, potresti doverlo arrotolare come nel seguente codice (usando una semplice regola di ordinamento per la leggibilità :-)).

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

O semplicemente usa heapq.merge.
cs95,

7

È possibile utilizzare il append()metodo definito sugli listoggetti:

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

9
solo così sai, se questo è ciò che stai facendo in pratica, questo è molto, molto più lento rispetto agli altri metodi proposti. vedi stackoverflow.com/questions/17479361/…
Ryan Haining,

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

Il codice sopra, non conserva l'ordine, rimuove i duplicati da ogni elenco (ma non dall'elenco concatenato)


6

Come già sottolineato da molti, itertools.chain()è la strada da percorrere se si deve applicare esattamente lo stesso trattamento ad entrambe le liste. Nel mio caso, avevo un'etichetta e una bandiera che erano diverse da una lista all'altra, quindi avevo bisogno di qualcosa di leggermente più complesso. A quanto pare, dietro le quinte itertools.chain()semplicemente fa quanto segue:

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

(vedi https://docs.python.org/2/library/itertools.html ), quindi ho preso ispirazione da qui e ho scritto qualcosa in questo senso:

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

I punti principali da capire qui sono che gli elenchi sono solo un caso speciale di iterabile, che sono oggetti come gli altri; e che i for ... inloop in Python possono funzionare con variabili tuple, quindi è semplice eseguire il loop su più variabili contemporaneamente.


5

Usa una semplice comprensione dell'elenco:

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

Presenta tutti i vantaggi del nuovo approccio dell'utilizzo di generalizzazioni di decompressione aggiuntive - vale a dire che puoi concatenare un numero arbitrario di iterabili diversi (ad esempio elenchi, tuple, intervalli e generatori) in questo modo - e non è limitato a Python 3.5 o successivo .


4

Un modo davvero conciso di combinare un elenco di elenchi è

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

che ci dà

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

Si prega di non utilizzare list.__add__, utilizzare operator.addinvece. Questo è l'equivalente più prolisso di sum(list_of_lists, [])cui è altrettanto cattivo. NON USARE!
cs95,

@ cs95 puoi spiegare qual è il problema usando la lista .__ add__
Akash Singh,

i metodi dunder sono "metodi privati" e in genere non devono essere utilizzati direttamente (sono chiamati da altre funzioni). Le eccezioni sono obj.__class__e obj.__dict__.
cs95,

3

In Python puoi concatenare due matrici di dimensioni compatibili con questo comando

numpy.concatenate([a,b])

4
La domanda non chiede intorpidimento.
cs95,

2

Quindi ci sono due modi semplici.

  1. Utilizzo+ : crea un nuovo elenco dagli elenchi forniti

Esempio:

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. Utilizzo di extender : aggiunge un nuovo elenco all'elenco esistente. Ciò significa che non crea un elenco separato.

Esempio:

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

Quindi vediamo che su due dei metodi più popolari, extendè efficiente.


2
Cosa succede se devo aggiungere più elenchi, come a + b + c + d + e?
Tweakimp,

2
@Tweakimp Vedi questa risposta che ha un paio di opzioni (mi raccomando chain.from_iterable).
cs95,

2

Esistono diversi modi per concatenare gli elenchi in 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
Potresti spiegare quali nuove informazioni fornisce questa risposta rispetto alle altre?
cs95,

Esistono diversi modi per concatenare gli elenchi in Python , che sono tutti ampiamente trattati in altre risposte molto più vecchie. Quali nuove informazioni fornisce questo ??
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))

Produzione:

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]

-1

Se volevi un nuovo elenco mantenendo le due vecchie liste:

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

    sorted(joinedList)

    return joinedList

In che modo differisce da questa risposta di 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]

4
Bene, per favore fai qualche spiegazione
U10-Forward

Qual è il punto degli argomenti della funzione se stai usando i nomi globali al suo interno?
Tomerikoo,

-2

Puoi seguire il codice

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

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

[1,2,3,4,5,6]
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.