Пропустить несколько итераций в цикле python

у меня есть список в цикле, и я хочу пропустить 3 элемента после look была достигнута. В ответ было сделано несколько предложений, но я не могу хорошо использовать их:

song = ['always', 'look', 'on', 'the', 'bright', 'side', 'of', 'life']
for sing in song:
    if sing == 'look':
        print sing
        continue
        continue
        continue
        continue
        print 'a' + sing
    print sing

четыре раза continue это нонсенс, конечно, и использование четыре раза next() не работает.

вывод должен выглядеть так:

always
look
aside
of
life

6 ответов


for использует iter(song) to loop; вы можете сделать это в своем собственном коде, а затем продвинуть итератор внутри цикла; вызов iter() на iterable снова будет возвращать только тот же объект iterable, так что вы можете продвигать iterable внутри цикла с for следуя прямо в следующей итерации.

продвиньте итератор с помощью next() функции; он работает правильно в Python 2 и 3 без необходимости настройки синтаксис:

song = ['always', 'look', 'on', 'the', 'bright', 'side', 'of', 'life']
song_iter = iter(song)
for sing in song_iter:
    print sing
    if sing == 'look':
        next(song_iter)
        next(song_iter)
        next(song_iter)
        print 'a' + next(song_iter)

двигаясь на print sing построиться мы можем избежать повторения себя тоже.

используя next() таким образом можете поднять StopIteration исключение, если у iterable нет значений.

вы могли бы поймать это исключение, но было бы легче дать next() второй аргумент, значение по умолчанию для игнорирования исключения и возврата значения по умолчанию:

song = ['always', 'look', 'on', 'the', 'bright', 'side', 'of', 'life']
song_iter = iter(song)
for sing in song_iter:
    print sing
    if sing == 'look':
        next(song_iter, None)
        next(song_iter, None)
        next(song_iter, None)
        print 'a' + next(song_iter, '')

я хотел бы использовать itertools.islice() пропустить 3 элемента вместо этого; сохраняет повторенные next() вызовы:

from itertools import islice

song = ['always', 'look', 'on', 'the', 'bright', 'side', 'of', 'life']
song_iter = iter(song)
for sing in song_iter:
    print sing
    if sing == 'look':
        print 'a' + next(islice(song_iter, 3, 4), '')

на islice(song_iter, 3, 4) iterable пропустит 3 элемента, затем вернет 4-й, затем будет сделано. Зову next() на этом объекте таким образом извлекает 4-й элемент из song_iter().

демо:

>>> from itertools import islice
>>> song = ['always', 'look', 'on', 'the', 'bright', 'side', 'of', 'life']
>>> song_iter = iter(song)
>>> for sing in song_iter:
...     print sing
...     if sing == 'look':
...         print 'a' + next(islice(song_iter, 3, 4), '')
... 
always
look
aside
of
life

>>> song = ['always', 'look', 'on', 'the', 'bright', 'side', 'of', 'life']
>>> count = 0
>>> while count < (len(song)):
    if song[count] == "look" :
        print song[count]
        count += 4
        song[count] = 'a' + song[count]
        continue
    print song[count]
    count += 1

Output:

always
look
aside
of
life

Я думаю, это просто прекрасно, чтобы использовать итераторы и next здесь:

song = ['always', 'look', 'on', 'the', 'bright', 'side', 'of', 'life']
it = iter(song)
while True:
    word = next(it, None)
    if not word:
       break
    print word
    if word == 'look':
        for _ in range(4): # skip 3 and take 4th
            word = next(it, None)
        if word:
            print 'a' + word

или, с обработкой исключений (которая короче, а также более надежна ,как заметил @ Steinar):

it = iter(song)
while True:
    try:
        word = next(it)
        print word
        if word == 'look':
            for _ in range(4):
                word = next(it)
            print 'a' + word 
    except StopIteration:
        break

конечно, вы можете использовать три раза в следующий раз (здесь я на самом деле делаю это четыре раза)

song = ['always', 'look', 'on', 'the', 'bright', 'side', 'of', 'life']
it = iter(song)
for sing in it:
    if sing == 'look':
        print sing
        try:
           sing = it.next(); sing = it.next(); sing = it.next(); sing=it.next()
        except StopIteration:
             break
        print 'a'+sing
    else:
        print sing

затем

always
look
aside
of
life

на самом деле, используя .next () три раза-это не ерунда. Если вы хотите пропустить n значений, вызовите next () n+1 раз (не забудьте присвоить значение последнего вызова чему-либо), а затем "вызов" продолжится.

чтобы получить точную копию кода, который вы выложили:

song = ['always', 'look', 'on', 'the', 'bright', 'side', 'of', 'life']
songiter = iter(song)
for sing in songiter:
  if sing == 'look':
    print sing
    songiter.next()
    songiter.next()
    songiter.next()
    sing = songiter.next()
    print 'a' + sing
    continue
  print sing

вы можете сделать это без iter (), а также просто с помощью дополнительной переменной:

skipcount = -1
song = ['always', 'look', 'on', 'the', 'bright', 'side', 'of', 'life']
for sing in song:
    if sing == 'look' and skipcount <= 0:
        print sing
        skipcount = 3
    elif skipcount > 0:
        skipcount = skipcount - 1
        continue
    elif skipcount == 0:
        print 'a' + sing
        skipcount = skipcount - 1
    else:
        print sing
        skipcount = skipcount - 1