2009-04-07 14 views
110

Was ist der Unterschied zwischen ist:In Python, was ist der Unterschied zwischen ".append()" und "+ = []"?

some_list1 = [] 
some_list1.append("something") 

und

some_list2 = [] 
some_list2 += ["something"] 
+3

append, wenn für ein einzelnes Element. vielleicht meinst du "verlängern". – hasen

+0

Für den interessanteren Fall von '+ =' vs 'extend ': http://stackoverflow.com/questions/3653298/concatenating-two-lists-difference-between-and-extend –

Antwort

153

Für Ihren Fall ist der einzige Unterschied die Leistung: append 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 Fall append wird ein Element zur Liste hinzufügen, während +=alle Elemente der rechten seitige Liste in der linken seitige Liste kopiert.

Update: perf Analyse

Bytecode Vergleich können wir die append Version Abfälle Zyklen in LOAD_ATTR + CALL_FUNCTION und + = Version übernehmen - in BUILD_LIST. Offensichtlich überwiegt BUILD_LISTLOAD_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 Leistung verbessern können noch mehr von LOAD_ATTR Kopf entfernt wurde:

>>> timeit.Timer('a("something")', 's = []; a = s.append').timeit() 
0.15924410999923566 
+8

+1: Das ist sehr interessant. Ich benutze sowieso anhängen, weil es zu klareren Code führt. Aber ich wusste nicht, dass es einen Leistungsunterschied gab. Wenn überhaupt, hätte ich erwartet, dass append langsamer ist, da es ein garantierter Funktionsaufruf ist, während ich annahm, dass + = weiter optimiert würde. – DNS

+0

Gibt es nicht auch einen funktionalen Unterschied? Zum Beispiel lassen Sie ** a = [] **, ** b = [4,5,6] **, hier, wenn Sie ** c = a.append (b) ** dann c wäre eine Liste der Liste ** [[4,5,6]] ** während ** c + = b **; würde zu einer einfachen Liste führen ** c = [4,5,6] **. – rkioji

+0

nur um Dinge klar zu stellen: + = gibt eine bessere Leistung als erweitern oder anhängen, solange Ihre Eingabe im richtigen Format ist. Was im gegenwärtigen Beispiel Zeit braucht, ist die Erstellung der Liste ['Something']. + = ist etwa 15% schneller – Joe

48

Im Beispiel Sie gab, gibt es keinen Unterschied in Bezug auf die Leistung, zwischen append und +=. Aber es gibt einen Unterschied zwischen append und + (zu der 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 += haben das gleiche Ergebnis; Sie fügen das Element zur Liste hinzu, ohne eine neue Liste zu erstellen. Die Verwendung von + fügt die zwei Listen hinzu und erzeugt eine neue Liste.

+0

There * ist * Unterschied zwischen append und + =. – Constantin

+3

Es gibt die Tatsache, dass 'append' einen Eintrag zu der Liste hinzufügt, während + = so viele addiert wie es in der anderen Liste gibt (d. H. Aliase zu' extend'). Aber das weiß er schon, nach der Art zu urteilen, wie die Frage geschrieben wurde. Gibt es einen anderen Unterschied, den ich vermisse? – DNS

+1

Es gibt einen Unterschied, weil eine erweiterte Zuweisung eine Neubindung einführt (Erklärung in meiner Antwort). – bobince

20
some_list2 += ["something"] 

ist eigentlich

some_list2.extend(["something"]) 

für einen Wert, gibt es keinen Unterschied. Dokumentation, besagt, dass:

s.append(x) gleiche wie s[len(s):len(s)] = [x]
s.extend(x) gleiche wie s[len(s):len(s)] = x

So offensichtlich s.append(x) ist die gleiche wie s.extend([x])

39
>>> a=[] 
>>> a.append([1,2]) 
>>> a 
[[1, 2]] 
>>> a=[] 
>>> a+=[1,2] 
>>> a 
[1, 2] 

sehen, dass ein einzelnes Element fügt anhängen zu die Liste, die alles sein kann. +=[] verbindet die Listen.

+2

Wählen Sie dies, weil dies ein wichtiger Unterschied zwischen den beiden ist. Gute Arbeit. – sli

3

Zusätzlich zu den in den anderen Antworten beschriebenen Aspekte, hängen und + [] haben sehr unterschiedliche Verhaltensweisen, wenn Sie versuchen, um 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]] 

liste1 + [ '5', '6'] fügt '5' und '6' an die liste1 als Einzelelement. list1.append (['5', '6']) fügt die Liste ['5', '6'] der Liste1 als einzelnes Element hinzu.

27

+ = ist eine Zuweisung. Wenn Sie es verwenden, sagen Sie wirklich 'some_list2 = some_list2 + [' something ']'. Zuordnungen beinhalten Rebinding, so:

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 in der Regel auch eine neue Liste Objekt wie Liste + Liste erstellen normalerweise der Fall ist:

>>> l1= [] 
>>> l2= l1 

>>> l1.append('x') 
>>> l1 is l2 
True 

>>> l1= l1+['x'] 
>>> l1 is l2 
False 

jedoch in Wirklichkeit:

>>> l2= l1 
>>> l1+= ['x'] 
>>> l1 is l2 
True 

Dies liegt daran, dass Python Listen implementieren __iadd__(), um eine + = erweiterte Zuordnung Kurzschluss und Aufruf list.extend() statt. (Es ist ein bisschen eine seltsame Warze dies: es tut in der Regel, was Sie meinten, aber aus verwirrenden Gründen.)

Im Allgemeinen, wenn Sie eine bestehende Liste anhängen/erweitern, und Sie wollen den Verweis auf die gleiche Liste (anstatt eine neue zu erstellen), ist es am besten, explizit zu sein und bei den append()/extend() Methoden zu bleiben.

5

Die Leistungstests sind hier nicht richtig:

  1. Sie sollten das Profil nur einmal nicht ausgeführt werden.
  2. Wenn Sie Append vs. + = [] vergleichen, sollten Sie Append als lokale Funktion deklarieren.
  3. Zeit Ergebnisse sind unterschiedlich auf unterschiedlichen Versionen Python: 64 und 32 bit

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

+0

noch, die + = Tests auf dieser Seite verwendet '+ = [one_var]'. Wenn wir keine Listen erstellen, wird + = zur schnellsten Option. – Joe

1

Das Rebinding Verhalten in anderen Antworten does matter unter bestimmten Umständen erwähnt:

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

Das liegt daran, dass die erweiterte Zuweisung immer wieder bindet, auch wenn das Objekt an Ort und Stelle mutiert wurde. Das erneute Binden ist hier a[1] = *mutated list*, was nicht für Tupel funktioniert.

5

Der Unterschied besteht darin, dass concatenate wird die resultierende Liste abflachen, während append wird die Ebene intakt halten:

So zum Beispiel mit:

myList = [ ] 
listA = [1,2,3] 
listB = ["a","b","c"] 

Mit append, Sie enden mit einer Liste von Listen:

>> myList.append(listA) 
>> myList.append(listB) 
>> myList 
[[1,2,3],['a',b','c']] 

Mit concatenate stattdessen am Ende mit einer flachen Liste nach oben:

>> myList += listA + listB 
>> myList 
[1,2,3,"a","b","c"] 
Verwandte Themen