2013-07-24 22 views
16

В питоне я обычно цикл по диапазонам простоКак пропустить несколько итераций в цикле

, но теперь я хочу, чтобы пропустить несколько шагов в цикле. Более конкретно, я хочу что-то вроде continue(10), чтобы он пропускал весь цикл и увеличивал счетчик на 10. Если бы я использовал цикл for в C, я бы просто составил 10 до i, но в Python это действительно не работает ,

ответ

16

Вы не можете изменить целевой список (i в данном случае) цикла for. Используйте while петлю вместо:

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

В качестве альтернативы, использовать итератора и приращение, что:

from itertools import islice 

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

Назначив результат iter() к локальной переменной, мы можем заранее последовательность петли внутри петли, используя стандартные итерационные инструменты (next(), или здесь, сокращенная версия рецепта потребления itertools). for обычно звонит iter() для нас при переходе по итератору.

+4

Я подумал, что может быть, в то время как петли просто грустно, хотя. –

+0

В любом случае закончен с циклом while! Благодаря тонну! –

+0

@AlexS Если вы итерируете по номерам, это нормально - если вы используете эти числа в качестве индексов для списков или чего-то еще, не делайте этого. Итерация по индексу плоха во всех отношениях. –

20

Лучший способ - присвоить итератору имя - обычно имеет итерабельность, в отличие от итератора (различие, являющееся итерабельным - например, список - начинается с начала каждый раз, когда вы перебираете его). В этом случае, просто использовать the iter() built-in function:

numbers = iter(range(100)) 

Затем вы можете продвигать его в цикле, используя имя. Лучший способ сделать это - the itertoolsconsume() recipe - так как он работает быстро (он использует функции itertools, чтобы гарантировать, что итерация происходит в низкоуровневом коде, что делает процесс потребления значений очень быстрым и позволяет избежать использования памяти, сохраняя потребляемые значения):

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) 

делая это, вы можете сделать что-то вроде:

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

Обратите внимание, что даже в Python 3 вы * имеете * для вызова 'iter()' on 'range()' для этого. Объект Python 3 'range()' является последовательностью (итерабельным), а не итератором. –

+0

@MartijnPieters Невероятно хорошая точка. Ред. Я немного перебираю диапазоны, я забыл, что это так. –

+0

Отличный ответ +1 –

4

Почему не просто установить значение не пропустить, пока? Как:

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

где SOME_CONDITION является то, что заставляет вас пропустить и do_something() является фактическим содержанием цикла?

+0

+1, 'continue' является наименее запутанным способом. – 2rs2ts

+0

Стоит отметить, что для этого требуется, чтобы цикл выполнялся в Python, и имя назначалось каждый раз - хотя в большинстве случаев это вряд ли будет проблемой, в этом смысле оно намного менее эффективно. –

+0

Да, но, учитывая простоту вопроса, я подумал, что ему нужен простой ответ; беспорядок с итераторами кажется излишним, если петли/пропуски малы. –

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

напечатает 0, 10, 20 ...

+1

Привет, хотя это пропускает первые 10 значений, я думаю, что ассер был больше заинтересован в том, чтобы узнать, как пропустить вперед до произвольного значения, а ** в цикле **. См. Главный ответ для примера. – seth

+0

Для этого вам определенно не нужен python 3.3. –

Смежные вопросы