Comment concaténer deux listes en Python?

2532

Comment concaténer deux listes en Python?

Exemple:

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

Résultat attendu:

>>> joinedlist
[1, 2, 3, 4, 5, 6]
y2k
la source
6
Voulez-vous simplement ajouter ou voulez-vous fusionner les deux listes dans l'ordre trié ? Quelle sortie attendez-vous pour [1,3,6] et [2,4,5]? Pouvons-nous supposer que les deux sous-listes sont déjà triées (comme dans votre exemple)?
smci
1
... et si les listes ont des doublons par exemple [1,2,5] and [2,4,5,6]? Voulez-vous que les doublons soient inclus, exclus ou peu importe?
smci

Réponses:

3906

Vous pouvez utiliser l' +opérateur pour les combiner:

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

joinedlist = listone + listtwo

Production:

>>> joinedlist
[1,2,3,4,5,6]
Daniel G
la source
110
cela crée-t-il une copie complète de listone et ajoute listtwo?
Daniel F
152
@Daniel crée une nouvelle liste avec une copie superficielle des éléments de la première liste, suivie d'une copie superficielle des éléments de la deuxième liste. Utilisez copy.deepcopy pour obtenir des copies complètes des listes.
Daniel G
219
un autre détail utile ici: listone += listtworésultats danslistone == [1, 2, 3, 4, 5, 6]
rickcnagy
16
@ br1ckb0t cela changera-t-il le pointage de la liste? Donc: la list3 = listone listone+=listtwo liste3 a-t-elle également changé?
MikeH
11
cela change list3. Cependant, si ce n'est pas un problème, il est plus simple et plus lisible d'ajouter les deux listes au lieu d'en créer une nouvelle.
rickcnagy
320

Il est également possible de créer un générateur qui itère simplement sur les éléments des deux listes à l'aide de itertools.chain(). Cela vous permet de chaîner des listes (ou tout itérable) ensemble pour les traiter sans copier les éléments dans une nouvelle liste:

import itertools
for item in itertools.chain(listone, listtwo):
    # Do something with each list item
Robert Rossney
la source
4
chainest plus lent (mais pas beaucoup) pour deux listes, mais est la solution la plus rapide pour chaîner plusieurs listes (n >> 2).
cs95
@ cs95 lent par rapport à quoi?
Moberg
@Moberg Par rapport à d'autres façons de concaténer des listes, pour référence, veuillez consulter mes références ici .
cs95
265

>= 3.5Alternative à Python :[*l1, *l2]

Une autre alternative a été introduite via l'acceptation PEP 448qui mérite d'être mentionnée.

Le PEP, intitulé Additional Unpacking Generalizations , a généralement réduit certaines restrictions syntaxiques lors de l'utilisation de l' *expression étoilée en Python; avec elle, la jonction de deux listes (s'applique à tout itérable) peut désormais aussi se faire avec:

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

Cette fonctionnalité a été définie pour Python,3.5 elle n'a pas été rétroportée vers les versions précédentes de la 3.xfamille. Dans les versions non prises en charge, un SyntaxErrorva être augmenté.

Comme pour les autres approches, cela crée également une copie superficielle des éléments dans les listes correspondantes.


L' avantage de cette approche est que vous n'avez vraiment pas besoin de listes pour l'exécuter, tout ce qui est itérable fera l'affaire. Comme indiqué dans le PEP:

Ceci est également utile comme moyen plus lisible de sommer les itérables dans une liste, comme celle my_list + list(my_tuple) + list(my_range)qui est maintenant équivalente à juste [*my_list, *my_tuple, *my_range].

Ainsi, alors que l'ajout avec +soulèverait une TypeErrorincompatibilité due au type:

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

Les éléments suivants ne seront pas:

res = [*l, *r]

car il déballera d'abord le contenu des itérables puis créera simplement un à listpartir du contenu.

Dimitris Fasarakis Hilliard
la source
1
Un bon exemple de l'approche de décompression fonctionnant sur des types itérables est les fonctions qui renvoient un itérateur sur l'une des listes que vous concaténez. Par exemple, vous pouvez inverser l' une des listes vous concaténer: res = [*l1, *reversed(l2)]. Puisque reversedrenvoie un itérateur, res = l1 + reversed(l2)lancerait une erreur.
alan
2
Il convient de noter que cela est analogue à la combinaison de dictionnaires en python. dict3 = {** dict1, ** dict2}. Notez que nous utilisons ** pour décompresser le dictionnaire alors qu'avec les listes, nous utilisons * pour décompresser.
Kevin S
213

Vous pouvez utiliser des ensembles pour obtenir une liste fusionnée de valeurs uniques

mergedlist = list(set(listone + listtwo))
Radagast
la source
45
Il est vrai, cependant, qu'il supprimera également les doublons, si c'est ce qui vous intéresse. L'ajout d'une liste ne ferait pas cela.
metasoarous
1
Comment procéder et conserver les informations de commande?
Natim
11
Mieux quelistone + [x for x in listtwo if x not in listone]
Natim
8
+1 À
mon humble avis,
2
Si vous vous souciez de maintenir l'ordre d'entrée, alors import collections; mergedlist = list(collections.OrderedDict.fromkeys(listone + listtwo))fera l'affaire.
SethMMorton
186

Vous pouvez également utiliser la list.extend()méthode afin d'ajouter un listà la fin d'un autre:

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

listone.extend(listtwo)

Si vous souhaitez conserver la liste d'origine intacte, vous pouvez créer un nouvel listobjet et les extenddeux listes:

mergedlist = []
mergedlist.extend(listone)
mergedlist.extend(listtwo)
Gourneau
la source
82

Comment concaténer deux listes en Python?

Depuis la version 3.7, ce sont les méthodes stdlib les plus populaires pour concaténer deux (ou plus) listes en python.

entrez la description de l'image ici

Notes de bas de page

  1. Il s'agit d'une solution lisse en raison de sa brièveté. Mais sumeffectue la concaténation par paire, ce qui signifie qu'il s'agit d'une opération quadratique car la mémoire doit être allouée pour chaque étape. NE PAS UTILISER si vos listes sont grandes.

  2. Voir chain et à chain.from_iterable partir des documents. Vous devrez d' import itertoolsabord. La concaténation est linéaire en mémoire, c'est donc le meilleur en termes de performances et de compatibilité de version. chain.from_iterablea été introduit en 2.6.

  3. Cette méthode utilise des généralisations de décompactage supplémentaires (PEP 448) , mais ne peut pas généraliser à N listes, sauf si vous décompressez chacune manuellement vous-même.

  4. a += bet a.extend(b)sont plus ou moins équivalents à toutes fins pratiques. +=lorsqu'il est appelé sur une liste, il appelle en interne list.__iadd__, ce qui étend la première liste par la seconde.


Performance

Concaténation 2 listes 1

entrez la description de l'image ici

Il n'y a pas beaucoup de différence entre ces méthodes mais cela a du sens étant donné qu'elles ont toutes le même ordre de complexité (linéaire). Il n'y a aucune raison particulière de préférer l'un à l'autre, sauf pour une question de style.

Concaténation de N-List

entrez la description de l'image ici

Les tracés ont été générés à l'aide du module perfplot . Code, pour votre référence.

1. Le iadd( +=) et les extendméthodes fonctionnent en place, une copie doit donc être générée à chaque fois avant le test. Pour garder les choses justes, toutes les méthodes ont une étape de pré-copie pour la liste de gauche qui peut être ignorée.


Commentaires sur d'autres solutions

  • N'UTILISEZ PAS LA MÉTHODE DUNDER list.__add__directement de quelque manière, forme ou forme. En fait, évitez les méthodes de détournement et utilisez les opérateurs et les operatorfonctions pour lesquels ils ont été conçus. Python a une sémantique minutieuse intégrée à ceux-ci qui sont plus compliqués que d'appeler directement le connard. Voici un exemple . Donc, pour résumer, a.__add__(b)=> BAD; a + b=> BON.

  • Certaines réponses offrent ici reduce(operator.add, [a, b])une concaténation par paire - c'est la même chose sum([a, b], [])que plus verbeux.

  • Toute méthode qui utilise setsupprimera les doublons et perdra l'ordre. Utiliser avec précaution.

  • for i in b: a.append(i)est plus verbeux et plus lent que a.extend(b), qui est un appel à fonction unique et plus idiomatique. appendest plus lent en raison de la sémantique avec laquelle la mémoire est allouée et développée pour les listes. Voir ici pour une discussion similaire.

  • heapq.mergefonctionnera, mais son cas d'utilisation est pour la fusion de listes triées en temps linéaire. L'utiliser dans toute autre situation est un anti-modèle.

  • yieldLier des éléments de liste à partir d'une fonction est une méthode acceptable, mais elle le chainfait plus rapidement et mieux (elle a un chemin de code en C, donc c'est rapide).

  • operator.add(a, b)est un équivalent fonctionnel acceptable de a + b. Ses cas d'utilisation sont principalement pour l'envoi de méthode dynamique. Sinon, préférez a + bce qui est plus court et plus lisible, à mon avis . YMMV.

cs95
la source
les réponses à stackoverflow.com/q/36863404/125507 pourraient utiliser un tracé de perfplot (y compris la solution numba)
endolith
@endolith bit inondé de travail mais je vais jeter un œil et voir si je peux y participer. Ty.
cs95
quelle est la meilleure méthode que les performances, plus rapide? s'il vous plaît, dites.
ganeshdeshmukh
@ganeshdeshmukh Le TL; DR est qu'ils sont tous bons et celui que vous choisissez est principalement une question de style. "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."Solutions non listées dans ma réponse, ou critiquées dans" Commentaires "Je recommande de ne pas les utiliser.
cs95
78

C'est assez simple, et je pense que cela a même été montré dans le tutoriel :

>>> listone = [1,2,3]
>>> listtwo = [4,5,6]
>>>
>>> listone + listtwo
[1, 2, 3, 4, 5, 6]
Tuure Laurinolli
la source
51

Cette question pose directement la question de joindre deux listes. Cependant, il est assez élevé dans la recherche même lorsque vous recherchez un moyen de joindre de nombreuses listes (y compris le cas lorsque vous rejoignez des listes nulles).

Je pense que la meilleure option est d'utiliser des listes de compréhension:

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

Vous pouvez également créer des générateurs:

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

Ancienne réponse

Considérez cette approche plus générique:

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

Sortira:

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

Notez que cela fonctionne également correctement lorsque aest []ou [[1,2,3]].

Cependant, cela peut être fait plus efficacement avec itertools:

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

Si vous n'avez pas besoin d'un list, mais simplement d'un itérable, omettez list().

Mise à jour

L'alternative suggérée par Patrick Collins dans les commentaires pourrait également vous convenir:

sum(a, [])
wonder.mice
la source
3
Remarque sur Python 3: reduceest désormais disponible functools, vous devrez donc l'importer en premier.
Dimitris Fasarakis Hilliard du
41

Vous pouvez simplement utiliser l' opérateur +or +=comme suit:

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

c = a + b

Ou:

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

c += (a + b)

De plus, si vous voulez que les valeurs de la liste fusionnée soient uniques, vous pouvez faire:

c = list(set(a + b))
Un mythe
la source
La dernière partie peut réorganiser arbitrairement les articles. Si vous voulez préserver l'ordre, sur CPython 3.6+, vous pouvez le fairelist(dict.fromkeys(a + b))
Boris
27

Il convient de noter que la itertools.chainfonction accepte un nombre variable d'arguments:

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

Si un itérable (tuple, liste, générateur, etc.) est l'entrée, la from_iterableméthode de classe peut être utilisée:

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

Avec Python 3.3+, vous pouvez utiliser le rendement de :

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]

Ou, si vous souhaitez prendre en charge un nombre arbitraire d'itérateurs:

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]

la source
Vous pouvez utiliser itertools.chain(ce qui est équivalent) au lieu de définir votre propre fonction.
Boris
18

Si vous souhaitez fusionner les deux listes sous forme triée, vous pouvez utiliser la mergefonction de la heapqbibliothèque.

from heapq import merge

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

print list(merge(a, b))
lavee_singh
la source
15

Si vous ne pouvez pas utiliser l'opérateur plus ( +), vous pouvez utiliser l' operatorimportation:

import operator

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

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

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

Alternativement, vous pouvez également utiliser la fonction __add__ dunder :

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

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

>>> [1, 2, 3, 4, 5, 6]
jpihl
la source
3
attraper des dunders n'est généralement pas la meilleure approche. Si +est hors de la table, utilisez operator.add.
Dimitris Fasarakis Hilliard
2
Pourquoi l'opérateur plus ne serait-il pas disponible?
cs01
2
Normalement, ce ne serait pas le cas :) mais si vous effectuez une concaténation de liste avec la fonction map ou si vous souhaitez stocker la fonction add dans une variable, vous ne pouvez pas utiliser +.
jpihl
13

Comme moyen plus général pour plus de listes, vous pouvez les mettre dans une liste et utiliser la fonction itertools.chain.from_iterable()1 qui, sur la base de cette réponse, est le meilleur moyen d'aplatir une liste imbriquée:

>>> 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. Notez qu'il chain.from_iterable()est disponible dans Python 2.6 et versions ultérieures. Dans d'autres versions, utilisez chain(*l).

Kasramvd
la source
10

Si vous devez fusionner deux listes ordonnées avec des règles de tri complexes, vous devrez peut-être les faire rouler vous-même comme dans le code suivant (en utilisant une règle de tri simple pour plus de lisibilité :-)).

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])
Mr Shark
la source
Ou utilisez simplement heapq.merge.
cs95
7

Vous pouvez utiliser la append()méthode définie sur les listobjets:

mergedlist =[]
for elem in listone:
    mergedlist.append(elem)
for elem in listtwo:
    mergedlist.append(elem)
mingxiao
la source
9
juste pour que vous sachiez, si c'est ce que vous faites dans la pratique, c'est beaucoup, beaucoup plus lent que les autres méthodes proposées. voir stackoverflow.com/questions/17479361/…
Ryan Haining
7
list(set(listone) | set(listtwo))

Le code ci-dessus, ne préserve pas l'ordre, supprime les doublons de chaque liste (mais pas de la liste concaténée)

SuperNova
la source
6

Comme plusieurs l'ont déjà souligné, itertools.chain()c'est la voie à suivre si l'on doit appliquer exactement le même traitement aux deux listes. Dans mon cas, j'avais une étiquette et un drapeau qui étaient différents d'une liste à l'autre, j'avais donc besoin de quelque chose d'un peu plus complexe. En fin de compte, dans les coulisses fait itertools.chain()simplement ce qui suit:

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

(voir https://docs.python.org/2/library/itertools.html ), donc je me suis inspiré d'ici et j'ai écrit quelque chose dans ce sens:

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

Les principaux points à comprendre ici sont que les listes ne sont qu'un cas particulier d'itérables, qui sont des objets comme les autres; et que les for ... inboucles en python peuvent fonctionner avec des variables de tuple, il est donc simple de boucler sur plusieurs variables en même temps.

Francesco Marchetti-Stasi
la source
5

Utilisez une compréhension de liste simple:

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

Il présente tous les avantages de la nouvelle approche d'utilisation généralisations de décompression supplémentaires - c'est-à-dire que vous pouvez concaténer un nombre arbitraire d'itérables différents (par exemple, des listes, des tuples, des plages et des générateurs) de cette façon - et ce n'est pas limité à Python 3.5 ou version ultérieure .

z33k
la source
4

Une façon très concise de combiner une liste de listes est

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

ce qui nous donne

[1, 2, 3, 4, 5, 6, 7, 8, 9]
Akash Singh
la source
Veuillez ne pas utiliser list.__add__, utilisez operator.addplutôt. C'est l'équivalent le plus verbeux sum(list_of_lists, [])qui est tout aussi mauvais. NE PAS UTILISER!
cs95
@ cs95 pouvez-vous expliquer quel est le problème en utilisant list .__ add__
Akash Singh
Les méthodes dunder sont des "méthodes privées" et ne doivent généralement pas être utilisées directement (elles sont appelées par d'autres fonctions). Les exceptions sont obj.__class__et obj.__dict__.
cs95
3

En Python, vous pouvez concaténer deux tableaux de dimensions compatibles avec cette commande

numpy.concatenate([a,b])
Michael Grossmann
la source
4
La question ne demande pas numpy.
cs95
2

Il y a donc deux façons simples.

  1. Utilisation+ : il crée une nouvelle liste à partir des listes fournies

Exemple:

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. Utilisation de extend : il ajoute une nouvelle liste à la liste existante. Cela signifie qu'il ne crée pas de liste distincte.

Exemple:

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

Ainsi, nous voyons que sur deux des méthodes les plus populaires, extendest efficace.

Vishvajit Pathak
la source
2
Que faire si j'ai besoin d'ajouter plusieurs listes, comme a + b + c + d + e?
Tweakimp
2
@Tweakimp Voir cette réponse qui a quelques options (je recommande chain.from_iterable).
cs95
2

Il existe plusieurs façons de concaténer des listes en 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]
chatrapathi
la source
1
Pourriez-vous expliquer quelles nouvelles informations cette réponse fournit par rapport aux autres?
cs95
Il existe plusieurs façons de concaténer des listes en python - qui sont toutes largement couvertes par d'autres réponses beaucoup plus anciennes. Quelles nouvelles informations cela fournit-il ??
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))

Production:

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
la source
-1

Si vous vouliez une nouvelle liste tout en conservant les deux anciennes listes:

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
la source
En quoi est-ce différent de cette réponse de 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
la source
4
Eh bien, veuillez faire quelques explications
U10-Forward
Quel est l'intérêt des arguments de la fonction si vous utilisez les noms globaux à l'intérieur?
Tomerikoo
-2

Vous pouvez suivre le code

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

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

[1,2,3,4,5,6]
beau islam
la source