Was ist der Unterschied zwischen:
some_list1 = []
some_list1.append("something")
und
some_list2 = []
some_list2 += ["something"]
Was ist der Unterschied zwischen:
some_list1 = []
some_list1.append("something")
und
some_list2 = []
some_list2 += ["something"]
Antworten:
In Ihrem Fall ist der einzige Unterschied die Leistung: Das Anhängen ist doppelt so schnell.
Python 3.0 (r30:67507, Dec 3 2008, 20:14:27) [MSC v.1500 32 bit (Intel)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> import timeit
>>> timeit.Timer('s.append("something")', 's = []').timeit()
0.20177424499999999
>>> timeit.Timer('s += ["something"]', 's = []').timeit()
0.41192320500000079
Python 2.5.1 (r251:54863, Apr 18 2007, 08:51:08) [MSC v.1310 32 bit (Intel)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> import timeit
>>> timeit.Timer('s.append("something")', 's = []').timeit()
0.23079359499999999
>>> timeit.Timer('s += ["something"]', 's = []').timeit()
0.44208112500000141
Im Allgemeinen append
wird der Liste ein Element hinzugefügt, während alle Elemente der Liste auf der rechten Seite in die Liste auf der linken Seite +=
kopiert werden .
Update: Perf-Analyse
Beim Vergleich von Bytecodes können wir davon ausgehen, dass die append
Version Zyklen in LOAD_ATTR
+ CALL_FUNCTION
und + = version - in verschwendet BUILD_LIST
. Anscheinend BUILD_LIST
überwiegt LOAD_ATTR
+ CALL_FUNCTION
.
>>> import dis
>>> dis.dis(compile("s = []; s.append('spam')", '', 'exec'))
1 0 BUILD_LIST 0
3 STORE_NAME 0 (s)
6 LOAD_NAME 0 (s)
9 LOAD_ATTR 1 (append)
12 LOAD_CONST 0 ('spam')
15 CALL_FUNCTION 1
18 POP_TOP
19 LOAD_CONST 1 (None)
22 RETURN_VALUE
>>> dis.dis(compile("s = []; s += ['spam']", '', 'exec'))
1 0 BUILD_LIST 0
3 STORE_NAME 0 (s)
6 LOAD_NAME 0 (s)
9 LOAD_CONST 0 ('spam')
12 BUILD_LIST 1
15 INPLACE_ADD
16 STORE_NAME 0 (s)
19 LOAD_CONST 1 (None)
22 RETURN_VALUE
Wir können die Leistung noch weiter verbessern, indem wir den LOAD_ATTR
Overhead entfernen :
>>> timeit.Timer('a("something")', 's = []; a = s.append').timeit()
0.15924410999923566
append
vs vergleichen +=
, müssen Sie die Erstellung der Liste als Teil der Messung einbeziehen . Sonst wäre es eine andere Frage ( extend
vs +=
).
In dem von Ihnen angegebenen Beispiel gibt es keinen Unterschied in Bezug auf die Ausgabe zwischen append
und +=
. Aber es gibt einen Unterschied zwischen append
und +
(worüber die Frage ursprünglich gestellt wurde).
>>> a = []
>>> id(a)
11814312
>>> a.append("hello")
>>> id(a)
11814312
>>> b = []
>>> id(b)
11828720
>>> c = b + ["hello"]
>>> id(c)
11833752
>>> b += ["hello"]
>>> id(b)
11828720
Wie Sie sehen können append
und +=
das gleiche Ergebnis haben; Sie fügen das Element der Liste hinzu, ohne eine neue Liste zu erstellen. Mit +
fügt werden die beiden Listen hinzugefügt und eine neue Liste erstellt.
append
ein Eintrag zur Liste hinzugefügt wird, während + = so viele hinzufügt, wie in der anderen Liste vorhanden sind (dh Aliase zu extend
). Aber er / sie weiß das schon, gemessen an der Art und Weise, wie die Frage geschrieben wurde. Gibt es einen anderen Unterschied, den ich vermisse?
>>> a=[]
>>> a.append([1,2])
>>> a
[[1, 2]]
>>> a=[]
>>> a+=[1,2]
>>> a
[1, 2]
Sehen Sie, dass das Anhängen der Liste ein einzelnes Element hinzufügt, das alles sein kann. +=[]
schließt sich den Listen an.
+ = ist eine Aufgabe. Wenn Sie es verwenden, sagen Sie wirklich 'some_list2 = some_list2 + [' etwas ']'. Zuweisungen beinhalten das erneute Binden, also:
l= []
def a1(x):
l.append(x) # works
def a2(x):
l= l+[x] # assign to l, makes l local
# so attempt to read l for addition gives UnboundLocalError
def a3(x):
l+= [x] # fails for the same reason
Der Operator + = sollte normalerweise auch ein neues Listenobjekt erstellen, wie es list + list normalerweise tut:
>>> l1= []
>>> l2= l1
>>> l1.append('x')
>>> l1 is l2
True
>>> l1= l1+['x']
>>> l1 is l2
False
In Wirklichkeit jedoch:
>>> l2= l1
>>> l1+= ['x']
>>> l1 is l2
True
Dies liegt daran, dass Python-Listen __iadd __ () implementieren , um einen + = erweiterten Zuweisungskurzschluss zu erstellen und stattdessen list.extend () aufzurufen. (Es ist ein bisschen eine seltsame Warze: Sie macht normalerweise das, was Sie gemeint haben, aber aus verwirrenden Gründen.)
Wenn Sie eine vorhandene Liste anhängen / erweitern und den Verweis auf dieselbe Liste beibehalten möchten (anstatt eine neue zu erstellen), ist es im Allgemeinen am besten, explizit zu sein und bei append () / extens () zu bleiben. Methoden.
some_list2 += ["something"]
ist eigentlich
some_list2.extend(["something"])
Für einen Wert gibt es keinen Unterschied. In der Dokumentation heißt es:
s.append(x)
gleich wies[len(s):len(s)] = [x]
s.extend(x)
gleich wies[len(s):len(s)] = x
Somit ist offensichtlich s.append(x)
dasselbe wies.extend([x])
Der Unterschied besteht darin, dass durch Verketten die resultierende Liste reduziert wird , während durch Anhängen die Ebenen intakt bleiben:
So zum Beispiel mit:
myList = [ ]
listA = [1,2,3]
listB = ["a","b","c"]
Wenn Sie Anhängen verwenden, erhalten Sie eine Liste mit Listen:
>> myList.append(listA)
>> myList.append(listB)
>> myList
[[1,2,3],['a',b','c']]
Wenn Sie stattdessen verketten verwenden, erhalten Sie eine flache Liste:
>> myList += listA + listB
>> myList
[1,2,3,"a","b","c"]
Die Leistungstests hier sind nicht korrekt:
z.B
timeit.Timer ('für i in xrange (100): app (i)', 's = []; app = s.append'). timeit ()
Gute Tests finden Sie hier: http://markandclick.com/1/post/2012/01/python-list-append-vs.html
+= [one_var]
. Wenn wir das Erstellen von Listen weglassen, wird + = die schnellste Option.
Zusätzlich zu den in den anderen Antworten beschriebenen Aspekten verhalten sich Anhängen und + [] sehr unterschiedlich, wenn Sie versuchen, eine Liste von Listen zu erstellen.
>>> list1=[[1,2],[3,4]]
>>> list2=[5,6]
>>> list3=list1+list2
>>> list3
[[1, 2], [3, 4], 5, 6]
>>> list1.append(list2)
>>> list1
[[1, 2], [3, 4], [5, 6]]
list1 + ['5', '6'] fügt der Liste1 '5' und '6' als einzelne Elemente hinzu. list1.append (['5', '6']) fügt die Liste ['5', '6'] als einzelnes Element zur Liste1 hinzu.
Das in anderen Antworten erwähnte Rückbindungsverhalten spielt unter bestimmten Umständen eine Rolle:
>>> a = ([],[])
>>> a[0].append(1)
>>> a
([1], [])
>>> a[1] += [1]
Traceback (most recent call last):
File "<interactive input>", line 1, in <module>
TypeError: 'tuple' object does not support item assignment
Dies liegt daran, dass die erweiterte Zuweisung immer wieder neu bindet, selbst wenn das Objekt an Ort und Stelle mutiert wurde. Das erneute Binden hier ist zufällig a[1] = *mutated list*
, was bei Tupeln nicht funktioniert.
Nehmen wir zuerst ein Beispiel
list1=[1,2,3,4]
list2=list1 (that means they points to same object)
if we do
list1=list1+[5] it will create a new object of list
print(list1) output [1,2,3,4,5]
print(list2) output [1,2,3,4]
but if we append then
list1.append(5) no new object of list created
print(list1) output [1,2,3,4,5]
print(list2) output [1,2,3,4,5]
extend(list) also do the same work as append it just append a list instead of a
single variable
Die Methode append () fügt der vorhandenen Liste ein einzelnes Element hinzu
some_list1 = []
some_list1.append("something")
Hier wird also some_list1 geändert.
Aktualisiert:
Verwenden Sie +, um die Elemente von Listen (mehr als ein Element) in der vorhandenen Liste zu kombinieren, ähnlich der Erweiterung (wie von Flux korrigiert ).
some_list2 = []
some_list2 += ["something"]
Hier sind also some_list2 und ["etwas"] die beiden Listen, die kombiniert werden.
+=
gibt keine neue Liste zurück. In den häufig gestellten Fragen zur Programmierung heißt es: "... für Listen __iadd__
entspricht dem Aufrufen extend
der Liste und dem Zurückgeben der Liste. Deshalb sagen wir, dass für Listen +=
eine" Abkürzung "für list.extend
" ist. Sie können dies auch im CPython-Quellcode selbst sehen: github.com/python/cpython/blob/v3.8.2/Objects/…
extend
.