2013-10-10 5 views
19

Durante il loop su un elenco in Python, non è stato possibile modificare gli elementi senza una comprensione di lista. Per riferimento:Impossibile modificare gli elementi di elenco in un loop Python

li = ["spam", "eggs"] 
for i in li: 
    i = "foo" 

li 
["spam", "eggs"] 

li = ["foo" for i in li] 
li 
["foo", "foo"] 

Allora, perché non posso modificare gli elementi attraverso un ciclo in Python? C'è sicuramente qualcosa che mi manca, ma non so cosa. Sono sicuro che questo è un duplicato, ma non sono riuscito a trovare una domanda al riguardo e, se c'è un link, sarebbe più che sufficiente. Grazie in anticipo!

+3

Sede [questo] (http://stackoverflow.com/questions/4081217/how-to-modify-list-entries-during-for-loop), [questo] (http: // StackOverflow. it/questions/1637807/modifying-list-while-iterating) – devnull

risposta

21

Perché il modo for i in li funziona è qualcosa di simile:

for idx in range(len(li)): 
    i = li[idx] 
    i = 'foo' 

Quindi, se si assegna qualcosa a i, esso non influisce li[idx].

La soluzione è o quello che hai proposto, o scorrendo gli indici:

for idx in range(len(li)): 
    li[idx] = 'foo' 

o utilizzare enumerate:

for idx, item in enumerate(li): 
    li[idx] = 'foo' 
+0

Il looping degli indici non sembra funzionare per me, sto usando python 3.6. Non importa. Sto usando una fetta, ecco perché. – Valachio

8

Infatti con la lista di comprensione non si sta modificando l'elenco, è stanno creando una nuova lista e quindi assegnandola alla variabile che conteneva quella precedente.

In ogni caso, quando si esegue for i in li hai trovato una copia di ciascun valore di li a variabili i, non si ottiene il riferimento a una posizione in li, in modo da non sta modificando alcun valore in li.

Se si desidera modificare l'elenco si può fare con enumerate:

>>> li = ["spam", "eggs"] 
>>> for i,_ in enumerate(li): 
     li[i] = "foo" 
>>> li 
['foo', 'foo'] 

o con xrange (in Python 2.7, utilizzare gamma in Python 3):

>>> for i in xrange(len(li)): 
     li[i] = "foo" 
>>> li 
['foo', 'foo'] 

o con la comprensione della lista che hai mostrato nella tua domanda.

1

sono in grado di modificare una lista, mentre loop:

lst = range(10) // [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] 

for i, elem in enumerate(lst): 
    lst[i] = 0 // [0, 0, 0, 0, 0, 0, 0, 0, 0, 0] 
1

for element in li - si restituisce una copia di elementi, non l'elemento stesso.

soluzione per il vostro caso sarebbe:

for i in range(len(li)): 
    li[i] = 'foo' 
1

magari usando dizionari possono essere utili.

>>> li = {0: "spam", 1:"eggs"} 
    for k, v in li.iteritems(): 
     li[k] = "foo" 

>>> li 
{0: 'foo', 1: 'foo'}