149 Stimmen

Was ist in Python der Unterschied zwischen ".append()" und "+= []"?

Was ist der Unterschied zwischen:

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

y

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

181voto

Constantin Punkte 26508

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

Allgemeiner Fall append fügt einen Eintrag in die Liste ein, während += kopiert tous Elemente der Liste auf der rechten Seite in die Liste auf der linken Seite.

Update: Leistungsanalyse

Beim Vergleich von Bytecodes können wir davon ausgehen, dass append Version verschwendet Zyklen in LOAD_ATTR + CALL_FUNCTION und += Version -- in 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 Folgendes entfernen LOAD_ATTR Overhead:

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

58voto

dwc Punkte 22998
>>> a=[]
>>> a.append([1,2])
>>> a
[[1, 2]]
>>> a=[]
>>> a+=[1,2]
>>> a
[1, 2]

Sie sehen, dass append der Liste ein einzelnes Element hinzufügt, das alles Mögliche sein kann. +=[] schließt sich den Listen an.

53voto

DNS Punkte 35625

In dem von Ihnen angeführten Beispiel gibt es keinen Unterschied in Bezug auf die Leistung zwischen append y += . Aber es gibt einen Unterschied zwischen append y + (nach dem in der Frage ursprünglich gefragt 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 y += haben das gleiche Ergebnis: Sie fügen das Element zur Liste hinzu, ohne eine neue Liste zu erstellen. Verwendung von + addiert die beiden Listen und erstellt eine neue Liste.

32voto

bobince Punkte 512550

+= ist eine Zuweisung. Wenn Sie es verwenden, sagen Sie in Wirklichkeit: "some_list2= some_list2+['something']". Zuweisungen beinhalten eine erneute Bindung, 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 erzeugen, wie es list+list normalerweise tut:

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

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

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

Aber in Wirklichkeit:

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

Das liegt daran, dass Python-Listen die Funktion __iadd__() um eine um += erweiterte Zuweisung kurzzuschließen und stattdessen list.extend() aufzurufen. (Das ist eine etwas seltsame Warze: Normalerweise tut sie das, was Sie gemeint haben, aber aus verwirrenden Gründen).

Wenn Sie eine bestehende Liste anhängen/erweitern und den Verweis auf dieselbe Liste beibehalten wollen (anstatt eine neue zu erstellen), ist es im Allgemeinen am besten, explizit zu sein und sich an die append()/extend()-Methoden zu halten.

22voto

vartec Punkte 124396
 some_list2 += ["something"]

ist eigentlich

 some_list2.extend(["something"])

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

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

Also offensichtlich s.append(x) ist identisch mit s.extend([x])

CodeJaeger.com

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.

Powered by:

X