Reputation: 256
So I know that there is already a question (Skip multiple iterations in loop) similar to mine with a really good answer, but there are still some open questions for me:
song = ['always', 'look', 'on', 'the', 'bright', 'side', 'of', 'life']
for sing in song:
print(sing, end=" ")
if sing == 'look':
continue * 3
expected output:
always look side of life
The original question has a solution like this:
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(next(song_iter))
But I want it to do it let's say x = 5 times. It is not possible like this:
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) * x
print(next(song_iter))
So how would you do it? I know it is possible to use the function itertools.islice
, but is there a way without any libraries?
song = ['always', 'look', 'on', 'the', 'bright', 'side', 'of', 'life']
song_iter = iter(song)
skip_iterations = 3
for sing in song_iter:
print(sing)
if sing == "look":
while skip_iterations > 0:
next(song_iter, "")
skip_iterations -= 1
Output:
always look side of life
But maybe anyone else has a better idea? :)
The Question I was mentioning - The Answer for that question
Upvotes: 2
Views: 764
Reputation: 17352
I would consider the "historic" way of iterating.
song = ['always', 'look', 'on', 'the', 'bright', 'side', 'of', 'life']
i = 0
while i < len(song):
sing = song[i]
i += 1
print(sing, end=" ")
if sing == 'look':
i += 3
continue
# ... other code ...
Upvotes: 0
Reputation: 1
Question 1
You could employ the use of an iteration bound to keep track of when you can resume evaluation in the loop
song = ['always', 'look', 'on', 'the', 'bright', 'side', 'of', 'life']
iter_bound = -1
for i, sing in enumerate(song):
if i <= iter_bound:
continue
if sing == 'look':
iter_bound = i + 3
print(sing, end=" ")
If you use this very often in your code, you may want to code a function around it:
from typing import Iterable, Callable
def skip_n_on_condition(iterator: Iterable, condition: Callable, n_skips: int):
"""Loop over iterable and perform n_skips whenever the condition on the element is met"""
iter_bound = -1
for i, element in enumerate(iterator):
if i <= iter_bound:
continue
if condition(element):
iter_bound = i + 3
yield element
song = ['always', 'look', 'on', 'the', 'bright', 'side', 'of', 'life']
print(*skip_n_on_condition(song, lambda x: x == 'look', 3), end=" ")
Question 2
Since you know the number of times you will be looping, it may be better to use a for loop. It will also be an implementation that does not change the value of skip_iterations which you may not have expected.
song = ['always', 'look', 'on', 'the', 'bright', 'side', 'of', 'life']
song_iter = iter(song)
skip_iterations = 3
for sing in song_iter:
print(sing)
if sing == "look":
for _ in range(skip_iterations):
next(song_iter, "")
You could make the loop a one liner using a list comprehension.
song = ['always', 'look', 'on', 'the', 'bright', 'side', 'of', 'life']
song_iter = iter(song)
skip_iterations = 3
for sing in song_iter:
print(sing)
if sing == "look":
[next(song_iter, "") for _ in range(skip_iterations)]
Upvotes: 0
Reputation: 27640
With a skip counter:
song = ['always', 'look', 'on', 'the', 'bright', 'side', 'of', 'life']
skip = 0
for sing in song:
if skip:
skip -= 1
continue
print(sing, end=" ")
if sing == 'look':
skip = 3
Upvotes: 0
Reputation: 104082
An alternate approach is to have a C style for
loop that has more complete update logic:
def cfor(i, test_i, update_i):
while test_i(i):
yield i
i=update_i(i)
song = ['always', 'look', 'on', 'the', 'bright', 'side', 'of', 'life']
skip=3
for i in cfor(0,
lambda i: i<len(song),
lambda i: i+skip+1 if song[i]=='look' else i+1):
print(song[i], end=' ')
Or, that can just be a while
loop:
idx=0
while(idx<len(song)):
print(song[idx], end=' ')
idx+=skip+1 if song[idx]=='look' else 1
If your skip
is large, either of these would be faster.
You can also use enumerate
with a comprehension:
l=song.index('look')
' '.join([w for i,w in enumerate(song) if i<=l or i>(l+skip)])
Upvotes: 1
Reputation: 76
Ans 1 There are many ways to do the problem one of the easiest one would be by checking the index like
song = ['always', 'look', 'on', 'the', 'bright', 'side', 'of', 'life']
skip_iterations=3
for i,sing in enumerate(song):
if not song.index('look') < i < song.index('look')+skip_iterations+1:
print(sing, end=" ")
'enumerate' returns (index, element) Ans 2 Your method is just fine you may prefer a for loop instead of while loop but thats just a personal suggestion.
Upvotes: 1