Python append () vs. + Operator auf Listen, warum ergeben diese unterschiedliche Ergebnisse?


113

Warum führen diese beiden Operationen ( append()bzw. +) zu unterschiedlichen Ergebnissen?

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

Im letzten Fall gibt es tatsächlich eine unendliche Rekursion. c[-1]und csind die gleichen. Warum ist es bei der +Operation anders ?


1
Bei allem Respekt vor einer realisierbaren neuen Frage: Ich bin zur ursprünglichen Frage zurückgekehrt, um sie sauber zu halten (1 Frage pro Thread, siehe SO-FAQ). Bitte stellen Sie eine neue oder stellen Sie weitere Fragen in den Kommentarthreads unter jeder Antwort. Hinweis: Ihre Änderungen gehen nicht verloren. Klicken Sie auf den Verlauf und Sie können ihn kopieren / in eine neue Frage einfügen.
Abel


es scheint, dass es verschiedene ans gibt, aber nicht so. Wenn Sie mit dem Operator + einen Wert hinzufügen möchten, müssen Sie das Zeichen [] verwenden. c + = [c] gibt Ihnen das gleiche Ergebnis wie beim Anhängen.
Sharif Chowdhury

@ SharifChowdhury Ich glaube, Sie werden das gleiche Ergebnis
erzielen

Antworten:


142

Um das "Warum" zu erklären:

Die +Operation fügt die Array- Elemente dem ursprünglichen Array hinzu. Die array.appendOperation fügt das Array (oder ein beliebiges Objekt) in das Ende des ursprünglichen Arrays ein, was zu einem Verweis auf sich selbst an dieser Stelle führt (daher die unendliche Rekursion).

Der Unterschied besteht darin, dass die + -Operation spezifisch wirkt, wenn Sie ein Array hinzufügen (es ist wie andere überladen, siehe dieses Kapitel über Sequenzen), indem Sie das Element verketten. Die Append-Methode macht jedoch buchstäblich das, was Sie verlangen: Hängen Sie das Objekt auf der rechten Seite an, die Sie ihm geben (das Array oder ein anderes Objekt), anstatt seine Elemente zu übernehmen.

Eine Alternative

Verwenden extend()Sie diese Option, wenn Sie eine Funktion verwenden möchten, die dem Operator + ähnelt (wie auch andere hier gezeigt haben). Es ist nicht ratsam, das Gegenteil zu tun: zu versuchen, das Anhängen mit dem Operator + für Listen nachzuahmen (siehe meinen früheren Link zum Warum).

Wenig Geschichte

Zum Spaß ein wenig Geschichte: Die Geburt des Array-Moduls in Python im Februar 1993. Es mag Sie überraschen, aber Arrays wurden hinzugefügt, nachdem Sequenzen und Listen entstanden waren.


2
+1, weil ich immer genaue Informationen stimme. Links zu offiziellen Dokumenten sind immer ein Plus!
Nathanismus

10
Ein weiterer Teil von "Warum": Vernünftige Menschen erwarten +, symmetrisch zu sein: Liste mit Liste verketten.
Beni Cherniavsky-Paskin

1
+1, Guter Punkt Beni (obwohl ich es als "vernünftig" betrachten könnte, zu sagen "das Objekt auf der rechten Seite wird an das Array auf der linken Seite angehängt", finde das aktuelle Verhalten aber persönlich sinnvoller).
Abel

Wenn ein Element eine einzelne Zeichenfolge ist, z. B. s = 'Wort', l = ['dies', 'ist']. Dann sollten l.append (s) und l + s gleich sein. Hab ich recht?
user3512680

23

Der Verkettungsoperator +ist ein binärer Infix-Operator, der bei Anwendung auf Listen eine neue Liste zurückgibt, die alle Elemente jedes seiner beiden Operanden enthält. Die list.append()Methode ist eine Methode, mutatoran listdie das einzelne objectArgument (in Ihrem speziellen Beispiel die Liste c) an den Betreff angehängt wird list. In Ihrem Beispiel führt dies dazu c, dass ein Verweis auf sich selbst angehängt wird (daher die unendliche Rekursion).

Eine Alternative zur Verkettung '+'

Die list.extend()Methode ist auch eine Mutator-Methode, die ihre sequenceArgumentation mit dem Subjekt verknüpft list. Insbesondere werden alle Elemente sequencein Iterationsreihenfolge angehängt .

Eine beiseite

Gibt als Operator +das Ergebnis des Ausdrucks als neuen Wert zurück. Da es sich um eine nicht verkettete mutatorMethode handelt, wird die list.extend()Themenliste direkt geändert und es wird nichts zurückgegeben.

Arrays

Ich habe dies aufgrund der möglichen Verwirrung hinzugefügt, die die obige Antwort von Abel durch das Mischen der Diskussion von Listen, Sequenzen und Arrays verursachen kann. Arrayswurden Python nach Sequenzen und Listen hinzugefügt, um Arrays integraler Datentypen effizienter zu speichern. Nicht verwechseln arraysmit lists. Sie sind nicht gleich.

Aus den Array-Dokumenten :

Arrays sind Sequenztypen und verhalten sich sehr ähnlich wie Listen, mit der Ausnahme, dass der Typ der darin gespeicherten Objekte eingeschränkt ist. Der Typ wird zum Zeitpunkt der Objekterstellung mithilfe eines Typcodes angegeben, der aus einem einzelnen Zeichen besteht.


18

appendhängt ein Element an eine Liste an. Wenn Sie die Liste um die neue Liste erweitern möchten, müssen Sie sie verwenden extend.

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

4
Ich dachte, es ist ziemlich klar, warum die Ergebnisse unterschiedlich sind, weil die Operationen nicht gleich sind! Wenn es so aussehen würde +und extendunterschiedliche Ergebnisse hervorbringen würden, hätten wir etwas zu überlegen.
SilentGhost

1
+1: Warum ich "Warum" -Fragen nicht mag: appendund +anders sind. Deshalb. Ich mag diese Antwort, weil Angebote, was zu tun ist, sinnvoller sind.
S.Lott

Geht es auf dieser Website nicht darum, die gestellten Fragen zu beantworten? Die Leute fragen, warum PHP PHP heißt und warum __lt__es in Python nicht überladen werden konnte (heutzutage kann es). Warum-Fragen sind die wichtigsten, aber oft die schwierigsten zu beantworten: Sie fragen nach der Essenz, nicht nach einem Hinweis auf das Handbuch. Und natürlich: Wenn du eine Frage nicht magst (ich mag die meisten nicht), dann antworte nicht ;-)
Abel

Zur weiteren Demonstration vielleicht auch zeigen c += [c]und c.append(c[:]).
Ephemient

2
@Abel: Warum ist a+b != a*b? Das sind verschiedene Operationen. Das ist die Antwort. "Warum" ist nicht so hilfreich wie andere Fragen wie "Wie kann ich richtig anhängen?" Oder "Was ist los mit diesem Anhang, der zu einer unendlichen Rekursion führt?" Fragen der Form "Was mache ich mit X" oder "Was ist schief gelaufen, als ich X gemacht habe"? Oder "Was soll ich anstelle von X tun?" Hilft auch jemandem beim Lernen, liefert jedoch fokussierte, verwendbare und umsetzbare Antworten.
S.Lott

8

Python-Listen sind heterogen, dh die Elemente in derselben Liste können beliebige Objekttypen sein. Der Ausdruck: c.append(c)Hängt das Objekt can die Liste an. In diesem Fall wird die Liste selbst zu einem Mitglied der Liste.

Der Ausdruck c += caddiert zwei Listen und weist der Variablen das Ergebnis zu c. Der überladene +Operator wird in Listen definiert, um eine neue Liste zu erstellen, deren Inhalt die Elemente in der ersten Liste und die Elemente in der zweiten Liste sind.

Das sind also wirklich nur verschiedene Ausdrücke, die verwendet werden, um verschiedene Dinge mit Absicht zu tun.


7

Die Methode, die Sie suchen, ist extend(). Aus der Python- Dokumentation :

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


2

Siehe die Dokumentation :

list.append (x)

  • Fügen Sie am Ende der Liste ein Element hinzu. äquivalent zu a [len (a):] = [x].

list.extend (L) - Erweitern Sie die Liste, indem Sie alle Elemente in der angegebenen Liste anhängen. äquivalent zu a [len (a):] = L.

c.append(c)"fügt" c als Element an sich selbst an . Da eine Liste ein Referenztyp ist, wird eine rekursive Datenstruktur erstellt.

c += cist äquivalent zu extend(c), wodurch die Elemente von c an c angehängt werden .

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.