2012-12-18 20 views
6

Sono nuovo di Python e sto sperimentando con gli elenchi Sto usando Python 3.2.3 (predefinito, 19 ottobre 2012, 20: 13:42), [GCC 4.6.3] sul linux2Perché un ciclo for con il metodo pop (o del statement) non itera su tutti gli elementi di lista

Ecco il mio SampleCode

>>> l=[1,2,3,4,5,6] 
>>> for i in l: 
...  l.pop(0) 
...  print(l) 
... 

mi aspetterei che il seguente output

1 
[2, 3, 4, 5, 6] 
2 
[3, 4, 5, 6] 
3 
[4, 5, 6] 
4 
[5, 6] 
5 
[6] 
6 
[] 

Invece sto ottenendo questo

1 
[2, 3, 4, 5, 6] 
2 
[3, 4, 5, 6] 
3 
[4, 5, 6] 

Il ciclo loop si interrompe dopo 3 giri. Qualcuno può spiegare perché?

+0

possibile duplicato di [Modifica elenco durante l'iterazione] (http://stackoverflow.com/questions/1637807/modifying-list-while-iterating) –

+0

@NedBatchelder: Mentre la causa principale è la stessa, la domanda è sostanzialmente diversa . Il motivo per cui si chiama 'pop' non è lo stesso (il collegamento sta tentando di saltare, questo non lo è). – Guvante

risposta

5

apertolo un po '(l'accento circonflesso (^) è al loop "indice"):

your_list = [1,2,3,4,5,6] 
      ^

dopo popping fuori il primo elemento:

your_list = [2,3,4,5,6] 
      ^

ora continuano il ciclo:

your_list = [2,3,4,5,6] 
      ^

Ora spegni il primo articolo:

your_list = [3,4,5,6] 
      ^

Ora continuano il ciclo:

your_list = [3,4,5,6] 
       ^

Ora pop off prima voce:

your_list = [4,5,6] 
       ^

Ora continua il ciclo - Aspetta, abbiamo finito. :-)


>>> l = [1,2,3,4,5,6] 
>>> for x in l: 
...  l.pop(0) 
... 
1 
2 
3 
>>> print l 
[4, 5, 6] 
+2

Davvero? È scritto con caratteri ortografici? Huh ... Ho sempre pensato che si chiamasse così perché sembrava una carota rovesciata ... Impara qualcosa di nuovo ogni giorno ... – mgilson

1

Python non supporta la modifica della lunghezza di un elenco mentre si itera su di esso. Lavorare su una copia o utilizzare un invece.

Pensa a come Python sta effettivamente eseguendo il ciclo for: esegue il conteggio attraverso gli elementi, restituendo l'elemento all'indice corrente. Quando ne rimuovi uno, l'indice indica un elemento diverso.

+0

In un caso potrebbe funzionare. Quando scatta l'ultimo elemento su ogni iterazione. –

+0

Potenzialmente ci sono situazioni in cui potrebbe funzionare. Non è qualcosa su cui dovresti fare affidamento, ci sono modi migliori. –

+2

Python supporta la modifica di un elenco mentre esegue iterazioni su di esso e funziona in modo coerente e prevedibile una volta compreso ciò che accade. A proposito, un'altra soluzione utile per alcuni casi d'uso è quella di operare sulla lista in ordine inverso. – kindall

2

È necessario fare attenzione quando si tenta di modificare le raccolte su cui si sta iterando. In questo caso, la lista tiene traccia della "posizione corrente" con un indice intero semplice. Quando si utilizza pop(), tutto cambia indice e quindi gli elementi vengono saltati.

Sulla prima iterazione del ciclo, i è l [0]. Quindi apri la lista, quindi accedi a [1], che è ciò che originariamente era a [2]. Quindi apri l'elenco e l'iterazione successiva accoda l [2], che è quello che era al [4], ecc.

Non c'è bisogno di inserire elementi in questo codice in ogni caso, presumibilmente si sta facendo qualcosa più complesso nel tuo codice reale.

-1

Si potrebbe utilizzare un ciclo while piuttosto che un ciclo for per questo compito.

while len(some_list)>0 : 
    some_list.pop(0) 

Un ciclo for sarà effettivamente iterare su ogni elemento della lista, che non funziona come gli indici nella lista cambieranno con ogni cancellazione, e non si finisce per ottenere tutti gli elementi.

Tuttavia, un ciclo while controlla una condizione ogni volta che viene eseguito il ciclo e, se è ancora true, esegue nuovamente il codice. Qui si specifica che la lunghezza dell'elenco deve essere maggiore di 0, cioè deve esserci il contenuto nell'elenco.