Was ist der Unterschied zwischen den Listenmethoden append()
y extend()
?
Was ist der Unterschied zwischen extend
und die einfache Verwendung des Additionsoperators - im obigen Beispiel, x = x + [4, 5]
?
Was ist der Unterschied zwischen den Listenmethoden append()
y extend()
?
Was ist der Unterschied zwischen extend
und die einfache Verwendung des Additionsoperators - im obigen Beispiel, x = x + [4, 5]
?
Eigentlich gibt es eine großer Unterschied - x + [4, 5]
gibt Ihnen eine neue Liste, die x zugeordnet ist - x.extend()
mutiert die ursprüngliche Liste. Ich erläutere dies in meiner Antwort weiter unten.
append
fügt ein Element zu einer Liste hinzu, und extend
verkettet die erste Liste mit einer anderen Liste (oder einer anderen Iterablen, die nicht unbedingt eine Liste ist).
>>> li = ['a', 'b', 'mpilgrim', 'z', 'example']
>>> li
['a', 'b', 'mpilgrim', 'z', 'example']
>>> li.append("new")
>>> li
['a', 'b', 'mpilgrim', 'z', 'example', 'new']
>>> li.append(["new", 2])
>>> li
['a', 'b', 'mpilgrim', 'z', 'example', 'new', ['new', 2]]
>>> li.insert(2, "new")
>>> li
['a', 'b', 'new', 'mpilgrim', 'z', 'example', 'new', ['new', 2]]
>>> li.extend(["two", "elements"])
>>> li
['a', 'b', 'new', 'mpilgrim', 'z', 'example', 'new', ['new', 2], 'two', 'elements']
Was ist der Unterschied zwischen den Listenmethoden append und extend?
append
fügt sein Argument als einzelnes Element an das Ende einer Liste an. Die Länge der Liste selbst wird um eins erhöht.extend
iteriert über sein Argument und fügt jedes Element der Liste hinzu, wodurch die Liste erweitert wird. Die Länge der Liste wird um die Anzahl der Elemente im Argument iterable erhöht.append
Le site list.append
Methode fügt ein Objekt an das Ende der Liste an.
my_list.append(object)
Was auch immer das Objekt ist, ob eine Zahl, eine Zeichenkette, eine andere Liste oder etwas anderes, es wird an das Ende von my_list
als einen einzigen Eintrag in die Liste.
>>> my_list
['foo', 'bar']
>>> my_list.append('baz')
>>> my_list
['foo', 'bar', 'baz']
Denken Sie also daran, dass eine Liste ein Objekt ist. Wenn Sie eine weitere Liste an eine Liste anhängen, wird die erste Liste ein einzelnes Objekt am Ende der Liste sein (was vielleicht nicht das ist, was Sie wollen):
>>> another_list = [1, 2, 3]
>>> my_list.append(another_list)
>>> my_list
['foo', 'bar', 'baz', [1, 2, 3]]
#^^^^^^^^^--- single item at the end of the list.
extend
Le site list.extend
Methode erweitert eine Liste durch Anhängen von Elementen aus einer Iterable:
my_list.extend(iterable)
Mit extend wird also jedes Element der Iterable an die Liste angehängt. Zum Beispiel:
>>> my_list
['foo', 'bar']
>>> another_list = [1, 2, 3]
>>> my_list.extend(another_list)
>>> my_list
['foo', 'bar', 1, 2, 3]
Denken Sie daran, dass eine Zeichenkette eine Iterable ist. Wenn Sie also eine Liste mit einer Zeichenkette erweitern, wird jedes Zeichen angehängt, während Sie über die Zeichenkette iterieren (was vielleicht nicht das ist, was Sie wollen):
>>> my_list.extend('baz')
>>> my_list
['foo', 'bar', 1, 2, 3, 'b', 'a', 'z']
__add__
( +
) und __iadd__
( +=
)Beide +
y +=
Operatoren sind definiert für list
. Sie sind semantisch ähnlich wie extend.
my_list + another_list
erstellt eine dritte Liste im Speicher, so dass Sie das Ergebnis davon zurückgeben können, aber es erfordert, dass die zweite iterable eine Liste ist.
my_list += another_list
ändert die Liste an Ort und Stelle (es es der In-Place-Operator, und Listen sind veränderbare Objekte, wie wir gesehen haben), also wird keine neue Liste erstellt. Es funktioniert auch wie extend, da die zweite Iterable jede Art von Iterable sein kann.
Lassen Sie sich nicht verwirren - my_list = my_list + another_list
ist nicht gleichbedeutend mit +=
- erhalten Sie eine brandneue Liste, die my_list zugewiesen ist.
Anhängen hat ( abgeschrieben ) konstante Zeitkomplexität , O(1).
Erweitern hat eine Zeitkomplexität von O(k).
Iteration durch die mehrfachen Aufrufe von append
fügt der Komplexität hinzu und macht sie äquivalent zu der von extend, und da die Iteration von extend in C implementiert ist, wird sie immer schneller sein, wenn Sie beabsichtigen, aufeinanderfolgende Elemente aus einer Iterablen an eine Liste anzuhängen.
Bezüglich "amortisiert" - von der list object implementation source :
/* This over-allocates proportional to the list size, making room
* for additional growth. The over-allocation is mild, but is
* enough to give linear-time amortized behavior over a long
* sequence of appends() in the presence of a poorly-performing
* system realloc().
Das bedeutet, dass wir die Vorteile einer größeren als der benötigten Speicherzuweisung im Voraus erhalten, aber bei der nächsten marginalen Neuzuweisung mit einer noch größeren Zuweisung dafür bezahlen. Die Gesamtzeit für alle Anhänge ist mit O(n) linear, und die Zeit, die pro Anhang zugewiesen wird, wird zu O(1).
Sie fragen sich vielleicht, was leistungsfähiger ist, da mit append das gleiche Ergebnis wie mit extend erreicht werden kann. Die folgenden Funktionen bewirken das Gleiche:
def append(alist, iterable):
for item in iterable:
alist.append(item)
def extend(alist, iterable):
alist.extend(iterable)
Wir sollten sie also zeitlich einordnen:
import timeit
>>> min(timeit.repeat(lambda: append([], "abcdefghijklmnopqrstuvwxyz")))
2.867846965789795
>>> min(timeit.repeat(lambda: extend([], "abcdefghijklmnopqrstuvwxyz")))
0.8060121536254883
Ein Kommentator sagte:
Perfekte Antwort, ich vermisse nur den Zeitpunkt des Vergleichs, indem ich nur ein Element hinzufüge
Tun Sie das semantisch Richtige. Wenn Sie alle Elemente in einer Iterable anhängen wollen, verwenden Sie extend
. Wenn Sie nur ein Element hinzufügen wollen, verwenden Sie append
.
Lassen Sie uns also ein Experiment durchführen, um zu sehen, wie sich dies in der Praxis bewährt:
def append_one(a_list, element):
a_list.append(element)
def extend_one(a_list, element):
"""creating a new list is semantically the most direct
way to create an iterable to give to extend"""
a_list.extend([element])
import timeit
Und wir sehen, dass es eine (geringe) Zeitverschwendung ist, eine iterable zu erstellen, nur um extend zu verwenden:
>>> min(timeit.repeat(lambda: append_one([], 0)))
0.2082819009956438
>>> min(timeit.repeat(lambda: extend_one([], 0)))
0.2397019260097295
Daraus lernen wir, dass es nichts bringt, wenn wir extend
wenn wir nur eine Element zum Anhängen.
Außerdem sind diese Zeitangaben nicht so wichtig. Ich zeige sie nur, um zu verdeutlichen, dass in Python das semantisch Richtige zu tun, bedeutet, die Dinge auf die richtige Weise zu tun. Rechts Way™.
Es ist denkbar, dass Sie die Zeitangaben für zwei vergleichbare Operationen testen und ein zweideutiges oder umgekehrtes Ergebnis erhalten. Konzentrieren Sie sich einfach darauf, das semantisch Richtige zu tun.
Wir sehen, dass extend
semantisch klarer ist und viel schneller laufen kann als append
, wenn Sie beabsichtigen, jedes Element in einer Iterable an eine Liste anzuhängen.
Wenn Sie der Liste nur ein einziges Element (nicht in einer Iterablen) hinzufügen möchten, verwenden Sie append
.
@Aaron Hall Eine kleine Anmerkung zum Algorithmus für das Timing. "extend_one" kann eine "leicht falsche" Zeit zurückgeben, da die Erstellung einer Liste ebenfalls involviert ist. Wahrscheinlich ist es besser, die Elemente als Variablen zu erstellen ( ex1 = 0
y ex2 = [0]
) und übergeben Sie diese Variablen, wenn Sie strenger sein wollen.
In der Tat eine perfekte Antwort. Was ist mit der Leistung von l1 += l2
gegen l1.extend(l2)
?
@Jean-FrancoisT.: l1 += l2
y l1.extend(l2)
letztlich denselben Code ausführen (die list_extend
Funktion in listobject.c
). Die einzigen Unterschiede sind: 1. +=
ordnet neu zu. l1
(an sich selbst für list
s, aber die Neuzuordnung unterstützt unveränderliche Typen, die danach nicht mehr dasselbe Objekt sind), was es illegal macht, wenn l1
ist eigentlich ein Attribut eines unveränderlichen Objekts; zum Beispiel, t = ([],)
, t[0] += lst
fehlschlagen würde, während t[0].extend(lst)
funktionieren würde. 2. l1 += l2
verwendet spezielle Bytecodes, während l1.extend(l2)
verwendet verallgemeinerten Methodenversand; dies macht +=
schneller als extend
.
Mit append können Sie ein einzelnes Element anhängen, das die Liste erweitert:
>>> a = [1,2]
>>> a.append(3)
>>> a
[1,2,3]
Wenn Sie mehr als ein Element erweitern wollen, sollten Sie extend verwenden, da Sie nur ein Element oder eine Liste von Elementen anhängen können:
>>> a.append([4,5])
>>> a
>>> [1,2,3,[4,5]]
Damit Sie eine verschachtelte Liste erhalten
Stattdessen können Sie mit extend ein einzelnes Element wie folgt erweitern
>>> a = [1,2]
>>> a.extend([3])
>>> a
[1,2,3]
Oder, anders als bei append, erweitern Sie mehrere Elemente auf einmal, ohne die Liste in die ursprüngliche einzuschachteln (das ist der Grund für den Namen extend)
>>> a.extend([4,5,6])
>>> a
[1,2,3,4,5,6]
Sowohl append als auch extend können ein Element an das Ende der Liste anfügen, wobei append einfacher ist.
>>> x = [1,2]
>>> x.append(3)
>>> x
[1,2,3]
>>> x = [1,2]
>>> x.extend([3])
>>> x
[1,2,3]
Wenn Sie append für mehr als ein Element verwenden, müssen Sie eine Liste von Elementen als Argumente übergeben und Sie erhalten eine NESTED-Liste!
>>> x = [1,2]
>>> x.append([3,4])
>>> x
[1,2,[3,4]]
Mit extend übergeben Sie stattdessen eine Liste als Argument, aber Sie erhalten eine Liste mit dem neuen Element, das nicht in der alten Liste verschachtelt ist.
>>> z = [1,2]
>>> z.extend([3,4])
>>> z
[1,2,3,4]
Wenn Sie also mehr Elemente haben, verwenden Sie extend, um eine Liste mit mehr Elementen zu erhalten. Durch das Anhängen einer Liste werden der Liste jedoch nicht mehr Elemente hinzugefügt, sondern ein Element, das eine verschachtelte Liste ist, wie Sie in der Ausgabe des Codes deutlich sehen können.
CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.