Qual è la differenza tra:In Python, qual è la differenza tra ".append()" e "+ = []"?
some_list1 = []
some_list1.append("something")
e
some_list2 = []
some_list2 += ["something"]
Qual è la differenza tra:In Python, qual è la differenza tra ".append()" e "+ = []"?
some_list1 = []
some_list1.append("something")
e
some_list2 = []
some_list2 += ["something"]
Per il tuo caso l'unica differenza è la prestazione: append è due volte più veloce.
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
In caso generale append
aggiungerà una voce alla lista, mentre +=
copierà tutti elementi della lista di destra-lato nella lista di sinistra-mano-lato.
Aggiornamento: perf analisi
Confrontando bytecode si può supporre che append
versione rifiuti cicli in LOAD_ATTR
+ CALL_FUNCTION
e + = versione - in BUILD_LIST
. A quanto pare BUILD_LIST
supera 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
Siamo in grado di migliorare le prestazioni ancora più rimuovendo LOAD_ATTR
testa:
>>> timeit.Timer('a("something")', 's = []; a = s.append').timeit()
0.15924410999923566
+1: questo è molto interessante. Io uso append comunque, perché risulta in un codice più chiaro. Ma non avevo capito che c'era una differenza di prestazioni. Se mai, mi sarei aspettato che append fosse più lenta, dal momento che è una chiamata di funzione garantita, mentre supponevo che + = sarebbe stata ulteriormente ottimizzata. – DNS
Non c'è anche una differenza funzionale? Per esempio lascia ** a = [] **, ** b = [4,5,6] **, qui se lo fai ** c = a.append (b) ** allora c sarebbe una lista di lista ** [[4,5,6]] ** mentre ** c + = b **; porterebbe a un elenco semplice ** c = [4,5,6] **. – rkioji
solo per impostare le cose: + = offre una prestazione migliore di estendere o aggiungere fino a quando l'input è nel formato giusto. Ciò che richiede tempo nell'esempio corrente è la creazione dell'elenco ['qualcosa']. + = è circa il 15% più veloce – Joe
Nell'esempio hai dato, non v'è alcuna differenza, in termini di produzione, tra il append
e +=
. Ma c'è una differenza tra append
e +
(che la domanda originariamente chiedeva).
>>> 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
Come si può vedere, append
e +=
avere lo stesso risultato; aggiungono l'elemento alla lista, senza produrre una nuova lista. L'utilizzo di +
aggiunge i due elenchi e produce un nuovo elenco.
Là * è * la differenza tra append e + =. – Constantin
C'è il fatto che 'append' aggiunge una voce alla lista, mentre + = aggiunge tante quante ce ne sono nell'altra lista (ad esempio alias di' extend'). Ma lui/lei lo sa già, a giudicare dal modo in cui la domanda è stata scritta. C'è qualche altra differenza che mi manca? – DNS
C'è una differenza perché un incarico ampliato introduce il rebinding (spiegazione nella mia risposta). – bobince
some_list2 += ["something"]
è in realtà
some_list2.extend(["something"])
per un valore, non c'è differenza. stati di documentazione, che:
s.append(x)
stesso comes[len(s):len(s)] = [x]
s.extend(x)
stessas[len(s):len(s)] = x
Così ovviamente s.append(x)
è stesse s.extend([x])
>>> a=[]
>>> a.append([1,2])
>>> a
[[1, 2]]
>>> a=[]
>>> a+=[1,2]
>>> a
[1, 2]
Sede che accoda aggiunge un singolo elemento di la lista, che può essere qualsiasi cosa. +=[]
si unisce alle liste.
Votare questo perché questa è una distinzione importante tra i due. Buon lavoro. – sli
Oltre agli aspetti descritti nelle altre risposte, aggiungere e + [] hanno comportamenti molto diversi quando si sta cercando per costruire una lista di liste.
>>> 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'] aggiunge '5' e '6' al list1 come singoli elementi. list1.append (['5', '6']) aggiunge la lista ['5', '6'] alla lista1 come un singolo elemento.
+ = è un compito. Quando lo usi, stai dicendo "some_list2 = some_list2 + ['something'] '. Assegnazioni coinvolgono rilegatura, quindi:
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
L'operatore + = dovrebbe anche normalmente creare un nuovo oggetto lista come lista lista + normalmente fa:
>>> l1= []
>>> l2= l1
>>> l1.append('x')
>>> l1 is l2
True
>>> l1= l1+['x']
>>> l1 is l2
False
Tuttavia nella realtà:
>>> l2= l1
>>> l1+= ['x']
>>> l1 is l2
True
Questo perché le liste Python implementano __iadd__() per effettuare un cor- to + = assegnazione aumentata e chiamare invece list.extend(). (È un po 'strano questo: di solito fa quello che volevi dire, ma per motivi di confusione.)
In generale, se stai aggiungendo/esteso un elenco esistente e vuoi mantenere il riferimento al stesso elenco (invece di crearne uno nuovo), è meglio essere espliciti e attenersi ai metodi append()/extend().
I test di prestazioni qui non sono corrette:
esempio
.timeit.Timer ('for i in xrange (100): app (i)', 's = []; app = s.append') timeit()
buoni test possono essere trovate qui: http://markandclick.com/1/post/2012/01/python-list-append-vs.html
, i test + = in quella pagina usano '+ = [one_var]'. Se omettiamo di creare elenchi, + = diventa l'opzione più veloce. – Joe
Il comportamento rilegatura detto in altre risposte non importa in determinate circostanze:
>>> 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
Ecco perché l'assegnazione aumentata si ricollega sempre, anche se l'oggetto è stato mutato sul posto. Il rebinding qui sembra essere a[1] = *mutated list*
, che non funziona per le tuple.
La differenza è che concatenate sarà appiattire la lista risultante, mentre accodamento manterrà i livelli intatti:
Così, per esempio con:
myList = [ ]
listA = [1,2,3]
listB = ["a","b","c"]
Utilizzando accodamento, si finisce con un elenco di elenchi:
>> myList.append(listA)
>> myList.append(listB)
>> myList
[[1,2,3],['a',b','c']]
Utilizzando concatenate, invece, si finisce con una semplice lista:
>> myList += listA + listB
>> myList
[1,2,3,"a","b","c"]
append se per un singolo elemento. forse intendi "estendi". – hasen
Per il caso più interessante di '+ =' vs 'extend': http://stackoverflow.com/questions/3653298/concatenating-two-lists-difference-between-and-extend –