Reputation: 149
I've created the following emulator function for itertools.cycle in python.
def cycle1(s) : while True : for i in s : yield i
However, I am not sure why the following produces a syntax error:
def cycle2(s) : return (i for i in s while True)
Why cannot I use while in list comprehension? How can I have an infinite loop within list comprehension?
Thank you.
Upvotes: 0
Views: 108
Reputation: 61526
Why cannot I use
while
in [the syntax for comprehensions and generator expressions]?
It just isn't defined to work that way. Maybe a future version might support it, if there is a clear proposal (PEP) and enough demand.
How can I have an infinite loop within list comprehension?
with a for
clause that loops over some unbounded generator. itertools
provides a couple of those: count
(produces increasing numbers endlessly) and repeat
(keeps yielding the same value, unless an explicit count is provided). Alternately, you can build it yourself from the built-in iter
:
>>> help(iter)
Help on built-in function iter in module builtins:
iter(...)
iter(iterable) -> iterator
iter(callable, sentinel) -> iterator
Get an iterator from an object. In the first form, the argument must
supply its own iterator, or be a sequence.
In the second form, the callable is called until it returns the sentinel.
The first version clearly doesn't help, but for the second, all we need is a callable that returns some value, and a sentinel value that is a different value. E.g. iter(lambda: True, False)
.
Upvotes: 1
Reputation: 5030
It raises error because that syntax is not defined in Python! You can try:
class MyGenerator:
def __init__(self,s):
self.s = s
self._ix = None
def __iter__(self):
return self
def __next__(self):
if self._ix is None:
self._ix = 0
self._ix = (self._ix + 1) % self.s
return self._ix
g = MyGenerator(5)
for i in range(20):
print(next(g))
Upvotes: 0