Introduction:
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:
Question 1:
Is there any way of doing it without an iterator?
I am looking for something like * 3: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
Question 2:
If I have to use an iterator object, then is it possible to do it a fixed amount of time?
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?
My Approach:
This works great: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? :)
Links:
The Question I was mentioning - The Answer for that question
CodePudding user response:
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.
CodePudding user response:
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)])
CodePudding user response:
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
CodePudding user response:
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)]
CodePudding user response:
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 ...