Python append () vs opérateur + sur les listes, pourquoi donnent-ils des résultats différents?

113

Pourquoi ces deux opérations ( append()resp. +) Donnent-elles des résultats différents?

>>> c = [1, 2, 3]
>>> c
[1, 2, 3]
>>> c += c
>>> c
[1, 2, 3, 1, 2, 3]
>>> c = [1, 2, 3]
>>> c.append(c)
>>> c
[1, 2, 3, [...]]
>>> 

Dans le dernier cas, il y a en fait une récursion infinie. c[-1]et csont les mêmes. Pourquoi est-ce différent avec l' +opération?

ooboo
la source
1
avec tout le respect que je dois à une nouvelle question viable: je suis revenu à la question d'origine pour la garder propre (1 question par fil, voir SO FAQ). Veuillez en poser une nouvelle ou poser des questions de suivi dans les fils de commentaires sous chaque réponse. Remarque: vos modifications ne sont pas perdues, cliquez sur l'historique et vous pouvez le copier / coller dans une nouvelle question.
Abel
Similaire pour +=: stackoverflow.com/questions/725782/…
Ciro Santilli 郝海东 冠状 病 六四 事件 法轮功
il semble que ça donne des ans différents, mais pas comme ça. Si vous souhaitez ajouter une valeur à l'aide de l'opérateur +, vous devez utiliser le signe []. c + = [c] vous donnera le même résultat que append.
Sharif Chowdhury
@SharifChowdhury Je crois que vous obtiendrez le même résultat
Trustory

Réponses:

142

Pour expliquer «pourquoi»:

L' +opération ajoute les éléments du tableau au tableau d'origine. L' array.appendopération insère le tableau (ou n'importe quel objet) à la fin du tableau d'origine, ce qui se traduit par une référence à soi à cet endroit (d'où la récursivité infinie).

La différence ici est que l'opération + agit de manière spécifique lorsque vous ajoutez un tableau (il est surchargé comme les autres, voir ce chapitre sur les séquences) en concaténant l'élément. La méthode append fait cependant littéralement ce que vous demandez: ajoutez l'objet sur le côté droit que vous lui donnez (le tableau ou tout autre objet), au lieu de prendre ses éléments.

Une alternative

À utiliser extend()si vous souhaitez utiliser une fonction qui agit de manière similaire à l'opérateur + (comme d'autres l'ont également montré ici). Il n'est pas sage de faire le contraire: d'essayer d'imiter append avec l'opérateur + pour les listes (voir mon lien précédent sur pourquoi).

Peu d'histoire

Pour le plaisir, un peu d'histoire: la naissance du module de tableau en Python en février 1993. cela pourrait vous surprendre, mais les tableaux ont été ajoutés bien après la création des séquences et des listes.

Abel
la source
2
+1 parce que je vote toujours des informations exactes. Les liens vers les documents officiels sont toujours un plus!
jathanism
10
Une autre partie du «pourquoi»: les gens sensés s'attendent +à être symétriques: concaténer la liste avec la liste.
Beni Cherniavsky-Paskin
1
+1, Bon point Beni (alors que je pourrais le considérer comme "sain" de dire "l'objet sur le côté droit est ajouté au tableau sur le côté gauche", mais je trouve personnellement le comportement actuel plus sensible).
Abel
si un élément est une chaîne unique, par exemple s = 'mot', l = ['ceci', 'est']. Ensuite, l.append (s) et l + s devraient être identiques. Ai-je raison?
user3512680 le
23

L'opérateur de concaténation +est un opérateur d'infixe binaire qui, lorsqu'il est appliqué aux listes, retourne une nouvelle liste contenant tous les éléments de chacun de ses deux opérandes. La list.append()méthode est un mutatorsur listlequel ajoute son objectargument unique (dans votre exemple spécifique, la liste c) au sujet list. Dans votre exemple, cela se traduit par l' cajout d'une référence à lui-même (d'où la récursivité infinie).

Une alternative à la concaténation '+'

La list.extend()méthode est également une méthode mutatrice qui concatène son sequenceargument avec le sujet list. Plus précisément, il ajoute chacun des éléments de sequencedans l'ordre d'itération.

Un aparté

Étant un opérateur, +renvoie le résultat de l'expression sous forme de nouvelle valeur. Étant une mutatorméthode sans chaînage , list.extend()modifie la liste de sujets sur place et ne renvoie rien.

Tableaux

J'ai ajouté cela en raison de la confusion potentielle que la réponse d'Abel ci-dessus peut causer en mélangeant la discussion sur les listes, les séquences et les tableaux. Arraysont été ajoutés à Python après les séquences et les listes, comme moyen plus efficace de stocker des tableaux de types de données intégraux. Ne confondez pas arraysavec lists. Ils ne sont pas les mêmes.

À partir de la documentation sur le tableau :

Les tableaux sont des types de séquence et se comportent très comme des listes, sauf que le type d'objets qui y sont stockés est contraint. Le type est spécifié au moment de la création de l'objet à l'aide d'un code de type, qui est un seul caractère.

Dave
la source
18

appendajoute un élément à une liste. si vous souhaitez étendre la liste avec la nouvelle liste que vous devez utiliser extend.

>>> c = [1, 2, 3]
>>> c.extend(c)
>>> c
[1, 2, 3, 1, 2, 3]
SilentGhost
la source
4
Je pensais que les raisons pour lesquelles les résultats étaient différents étaient assez claires , car les opérations ne sont pas les mêmes! si cela apparaîtrait +et extendproduirait des résultats différents auxquels nous aurions quelque chose à penser.
SilentGhost
1
+1: Pourquoi je n'aime pas les questions «pourquoi»: appendet +sont différentes. C'est pourquoi. J'aime cette réponse car elle propose ce que faire qui a plus de sens.
S.Lott
Ce site ne vise-t-il pas à répondre aux questions posées? Les gens se demandent pourquoi PHP s'appelle PHP et pourquoi __lt__ne peut pas être surchargé en Python (de nos jours, il le peut). Les questions sur le pourquoi sont les plus essentielles mais souvent les plus délicates à répondre: elles demandent l'essentiel, pas un pointeur vers le manuel. Et bien sûr: si vous n'aimez pas une question (je n'aime pas le plus), alors ne répondez pas ;-)
Abel
Pour plus de démonstration, peut-être montrer c += [c]et c.append(c[:])aussi.
éphémère du
2
@Abel: Pourquoi a+b != a*b? Ce sont des opérations différentes. Voilà la réponse. "Pourquoi" n'est pas aussi utile que d'autres questions, comme "Comment puis-je ajouter correctement?" Ou "Quel est le problème avec cet append qui conduit à une récursivité infinie?" Questions du formulaire "Que dois-je faire à X" ou "Qu'est-ce qui ne va pas quand j'ai fait X"? Ou «Que dois-je faire à la place de X» aidera également quelqu'un à apprendre, mais fournira des réponses ciblées, utilisables et exploitables.
S.Lott
8

Les listes Python sont hétérogènes, c'est-à-dire que les éléments d'une même liste peuvent être n'importe quel type d'objet. L'expression: c.append(c)ajoute l'objet cquel qu'il soit à la liste. Dans le cas où il fait de la liste elle-même un membre de la liste.

L'expression c += cajoute deux listes ensemble et affecte le résultat à la variable c. L' +opérateur surchargé est défini sur les listes pour créer une nouvelle liste dont le contenu est constitué des éléments de la première liste et des éléments de la seconde liste.

Ce ne sont donc que des expressions différentes utilisées pour faire différentes choses par conception.

Tendayi Mawushe
la source
7

La méthode que vous recherchez est extend(). À partir de la documentation Python :

list.append(x)
    Add an item to the end of the list; equivalent to a[len(a):] = [x].

list.extend(L)
    Extend the list by appending all the items in the given list; equivalent to a[len(a):] = L.

list.insert(i, x)
    Insert an item at a given position. The first argument is the index of the element before which to insert, so a.insert(0, x) inserts at the front of the list, and a.insert(len(a), x) is equivalent to a.append(x).
Chinmay Kanchi
la source
3

vous devriez utiliser extend ()

>>> c=[1,2,3]
>>> c.extend(c)
>>> c
[1, 2, 3, 1, 2, 3]

autres informations: ajouter ou étendre

ghostdog74
la source
2

Consultez la documentation :

list.append (x)

  • Ajoutez un élément à la fin de la liste; équivalent à a [len (a):] = [x].

list.extend (L) - Étend la liste en ajoutant tous les éléments de la liste donnée; équivalent à a [len (a):] = L.

c.append(c)"ajoute" c à lui-même en tant qu'élément . Puisqu'une liste est un type de référence, cela crée une structure de données récursive.

c += cest équivalent à extend(c), qui ajoute les éléments de c à c.

oefe
la source