how to use iterator in while loop statement in python
Solution 1
In Python >= 3.8, you can do the following, using assignment expressions:
i = iter(range(10))
while (x := next(i, None)) is not None and x < 5:
print(x)
In Python < 3.8 you can use itertools.takewhile
:
from itertools import takewhile
i = iter(range(10))
for x in takewhile({some logic}, i):
# do stuff
"Some logic" here would be a 1-arg callable receciving whatever next(i)
yields:
for x in takewhile(lambda e: 5 > e, i):
print(x)
0
1
2
3
4
Solution 2
There are two problems with while next(i):
- Unlike a
for
loop, thewhile
loop will not catch theStopIteration
exception that is raised if there is nonext
value; you could usenext(i, None)
to return a "falsey" value in that case, but then thewhile
loop will also stop whenever the iterator returns an actual falsey value - The value returned by
next
will be consumed and no longer available in the loop's body. (In Python 3.8+, that could be solved with an assignment expression, see other answer.)
Instead, you could use a for
loop with itertools.takewhile
, testing the current element from the iterable, or just any other condition. This will loop until either the iterable is exhausted, or the condition evaluates to false.
from itertools import takewhile
i = iter(range(10))
r = 0
for x in takewhile(lambda x: r < 10, i):
print("using", x)
r += x
print("result", r)
Output:
using 0
...
using 4
result 10
Solution 3
You just need to arrange for your iterator to return a false-like value when it expires. E.g., if we reverse the range
so that it counts down to 0:
>>> i = iter(range(5, -1, -1))
>>> while val := next(i):
... print('doing something here with value', val)
...
This will result in:
doing something here with value 5
doing something here with value 4
doing something here with value 3
doing something here with value 2
doing something here with value 1
Solution 4
a = iter(range(10))
try:
next(a)
while True:
print(next(a))
except StopIteration:
print("Stop iteration")
Related videos on Youtube
Union find
Updated on December 06, 2021Comments
-
Union find over 2 years
Is it possible to use a generator or iterator in a while loop in Python? For example, something like:
i = iter(range(10)) while next(i): # your code
The point of this would be to build iteration into the while loop statement, making it similar to a for loop, with the difference being that you can now additional logic into the while statement:
i = iter(range(10)) while next(i) and {some other logic}: # your code
It then becomes a nice for loop/while loop hybrid.
Does anyone know how to do this?
-
user2390182 over 4 yearshas to be a while-loop?
for x in i
would be the natural way. -
RomanPerekhrest over 4 yearsI guess you would not try your idea on
it = itertools.count(); while next(it):
-
Chris_Rands over 4 yearscan you give more context on your use case?
-
Chris Doyle over 4 yearshow would you access the value the iter returned since you dont store it you just take the item and evaluaate its boolean result so what would you do in the loop since you dont have access to the item returned from the iter?
-
RomanPerekhrest over 4 yearsWhat you need to elaborate is what should be a stopping factor of
while
loop. How aboutit = iter([True, False, 1, 0, 1]); while next(it): print('1')
? The answers given are simple, but what's your exact intention? -
Union find over 4 yearsWhat if we wanted to keep this general though, which is why I didn't indicate a specific additional logic. The stopping factor here can just be assumed to be exceeding the last iteration to where the iterator throws an exception. @RomanPerekhrest
-
-
tobias_k over 4 yearsBut this consumes
next(i)
, and if you call it again in the loop body you miss one value. Maybe with Python 3.8 assignment expressions, though. -
Chris_Rands over 4 years
while True and (True or False):
-- is this a joke? -
larsks over 4 yearsSure, this would be a prefect place to use assignment expressions. It wasn't clear from the question that you care about the value of the iterator.
-
larsks over 4 yearsUpdated the example to use an assignment expression.
-
Union find over 4 yearsEverything's getting downvoted.. this seems like a perfectly valid question/answer.
-
TOTO over 4 years@Chris_Rands No it's a substitute for his [some logic]
-
Union find over 4 yearsThis is exactly what I don't want to do. I want to put the next in the while statement.
-
Chris_Rands over 4 yearsgot it (not my dv), you should also use
next(a)
in py 3 -
gabriel garcia over 3 yearsThe
None
param is important or else it will throw anstopIteration
exception -
xing almost 3 yearsWhat if the element in the collection or streams is a None?
-
Admin over 2 yearsYour answer could be improved with additional supporting information. Please edit to add further details, such as citations or documentation, so that others can confirm that your answer is correct. You can find more information on how to write good answers in the help center.