Skip multiple iterations in loop

46,695

Solution 1

for uses iter(song) to loop; you can do this in your own code and then advance the iterator inside the loop; calling iter() on the iterable again will only return the same iterable object so you can advance the iterable inside the loop with for following right along in the next iteration.

Advance the iterator with the next() function; it works correctly in both Python 2 and 3 without having to adjust syntax:

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)

By moving the print sing line up we can avoid repeating ourselves too.

Using next() this way can raise a StopIteration exception, if the iterable is out of values.

You could catch that exception, but it'd be easier to give next() a second argument, a default value to ignore the exception and return the default instead:

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, '')

I'd use itertools.islice() to skip 3 elements instead; saves repeated next() calls:

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), '')

The islice(song_iter, 3, 4) iterable will skip 3 elements, then return the 4th, then be done. Calling next() on that object thus retrieves the 4th element from song_iter().

Demo:

>>> 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

Solution 2

>>> 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

Solution 3

I think, it's just fine to use iterators and next here:

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

or, with exception handling (which is shorter as well as more robust as @Steinar noticed):

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

Solution 4

You can do this without an iter() as well simply using an extra variable:

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

Solution 5

Actually, using .next() three times is not nonsense. When you want to skip n values, call next() n+1 times (don't forget to assign the value of the last call to something) and then "call" continue.

To get an exact replica of the code you posted:

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
Share:
46,695

Related videos on Youtube

Mehdi Nellen
Author by

Mehdi Nellen

First cat to be Master student in Molecular and Cellular Life Sciences at the University Utrecht.

Updated on July 09, 2022

Comments

  • Mehdi Nellen
    Mehdi Nellen almost 2 years

    I have a list in a loop and I want to skip 3 elements after look has been reached. In this answer a couple of suggestions were made but I fail to make good use of them:

    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
    

    Four times continue is nonsense of course and using four times next() doesn't work.

    The output should look like:

    always
    look
    aside
    of
    life
    
  • Martijn Pieters
    Martijn Pieters about 10 years
    This is rather unreadable though; it is really hard to work out what the intention is here.
  • SaeX
    SaeX about 10 years
    @MartijnPieters: agreed that there will be better solutions. Just wanted to point out a different approach.
  • Steinar Lima
    Steinar Lima about 10 years
    This works for the case presented, but be aware that any item which evaluates to False will break this solution (e.g ['always', 'look', '', 'the'] or ['always', 'look', None, 'the'])
  • Peteris
    Peteris about 10 years
    Works for that specific artificial example, but wouldn't work appropriately on arbitrary iterators/generators, where going to the next element or skipping is possible, but fetching an arbitrary element by index is either impossible (if they aren't stored) or slow.