2013-07-24 8 views
16

in Python di solito un ciclo tra le gamme semplicementeCome si salta un paio di iterazioni in un ciclo for

ma ora voglio saltare qualche passo nel ciclo. Più specificamente, voglio qualcosa come continue(10) in modo che salti l'intero ciclo e aumenti il ​​contatore di 10. Se stavo usando un ciclo for in C vorrei solo sommare 10 a i, ma in Python che non funziona davvero .

risposta

16

Non è possibile modificare l'elenco di destinazione (i in questo caso) di un ciclo for. Usare un ciclo while invece:

while i < 10: 
    i += 1 
    if i == 2: 
     i += 3 

alternativa, utilizzare un iterabile e incrementare che:

from itertools import islice 

numbers = iter(range(10)) 
for i in numbers: 
    if i == 2: 
     next(islice(numbers, 3, 3), None) # consume 3 

Assegnando il risultato di iter() a una variabile locale, possiamo avanzare la sequenza ciclo all'interno del ciclo usando strumenti di iterazione standard (next() o qui, una versione abbreviata della ricetta consumo itertools). for normalmente chiama iter() per noi quando si esegue il ciclo su un iteratore.

+4

Ho pensato che potrebbe essere il caso, mentre i cicli sono solo triste però. –

+0

Finito comunque di andare con il ciclo while! Grazie mille! –

+0

@AlexS Se si sta iterando su numeri, va bene - se si utilizzano quei numeri come indici per elenchi o qualsiasi altra cosa, si prega di non farlo. L'iterazione per indice è cattiva in ogni modo. –

20

Il modo migliore è assegnare all'iteratore un nome: è comune avere un iteratore in contrapposizione a un iteratore (la differenza essendo un iterabile, ad esempio un elenco, inizia dall'inizio ogni volta che si itera su di esso). In questo caso, basta usare the iter() built-in function:

numbers = iter(range(100)) 

Quindi è possibile avanzare all'interno del ciclo utilizzando il nome. Il modo migliore per farlo è con the itertoolsconsume() recipe - poiché è veloce (usa le funzioni itertools per garantire che l'iterazione avvenga nel codice di basso livello, rendendo il processo di consumo dei valori molto veloce ed evita di utilizzare la memoria memorizzando i valori consumati):

from itertools import islice 
import collections 

def consume(iterator, n): 
    "Advance the iterator n-steps ahead. If n is none, consume entirely." 
    # Use functions that consume iterators at C speed. 
    if n is None: 
     # feed the entire iterator into a zero-length deque 
     collections.deque(iterator, maxlen=0) 
    else: 
     # advance to the empty slice starting at position n 
     next(islice(iterator, n, n), None) 

In questo modo, si può fare qualcosa di simile:

numbers = iter(range(100)) 
for i in numbers: 
    ... 
    if some_check(i): 
     consume(numbers, 3) # Skip 3 ahead. 
+0

Nota che anche in Python 3, devi * chiamare * iter() 'su' range() 'affinché funzioni. L'oggetto Python 3 'range()' è una sequenza (un iterabile), non un iteratore. –

+0

@MartijnPieters Punto incredibilmente buono. Modificato. Ho iterato su intervalli così piccoli che ho dimenticato che era il caso. –

+0

Ottima risposta +1 –

4

Perché non basta impostare il valore di saltare fino a quando? Come:

skip_until = 0 
for i in range(100): 
    if i < skip_until: 
     continue 
    if SOME_CONDITION: 
     skip_until = i + 10 
    DO_SOMETHING() 

dove SOME_CONDITION è tutto ciò che ti fa saltare e fa_qualcosa() è il contenuto effettivo del ciclo?

+0

+1, 'continue' è il modo meno complesso. – 2rs2ts

+0

Vale la pena notare che ciò richiede che il ciclo venga eseguito in Python e che il nome venga assegnato ogni volta, mentre non è probabile che sia un problema nella maggior parte dei casi, in questo senso è molto meno efficiente. –

+0

Sì, ma vista la semplicità della domanda ho pensato che voleva una risposta semplice; scherzare con gli iteratori sembra eccessivo se i loop/skip sono piccoli. –

-2
for i in range(0, 100, 10): 
    print(i) 

stamperà 0, 10, 20 ...

+1

Salve, anche se questo salta i primi 10 valori, penso che il richiedente fosse più interessato a sapere come passare ad un valore arbitrario mentre ** nel ciclo **. Vedi la risposta più alta per un esempio. – seth

+0

Per questo, sicuramente non hai bisogno di Python 3.3. –

Problemi correlati