Take the 2-minute tour ×
Stack Overflow is a question and answer site for professional and enthusiast programmers. It's 100% free, no registration required.

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
share|improve this question
 
next() three times should work fine, so long as you iterate over iter(song). –  minitech 19 hours ago
add comment

6 Answers

up vote 16 down vote accepted

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
share|improve this answer
 
This doesn't print what's expected. –  hivert 19 hours ago
 
@hivert: It does now. –  Martijn Pieters 19 hours ago
 
dankjewel martijn! :) –  Mehdi Nellen 19 hours ago
1  
@MehdiNellen: Graag gedaan! –  Martijn Pieters 19 hours ago
 
Beautifully explained answer. –  Bach 18 hours ago
add comment

Of course you can use three time next (here I actually do it four time)

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

Then

always
look
aside
of
life
share|improve this answer
add comment

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|improve this answer
add comment

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
share|improve this answer
3  
This is rather unreadable though; it is really hard to work out what the intention is here. –  Martijn Pieters 19 hours ago
 
@MartijnPieters: agreed that there will be better solutions. Just wanted to point out a different approach. –  SaeX 19 hours ago
add comment
>>> 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
share|improve this answer
 
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. –  Peteris 13 hours ago
add comment

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
share|improve this answer
1  
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']) –  Steinar Lima 14 hours ago
 
@SteinarLima good point, thanks. –  bereal 14 hours ago
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.