New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Nested generator terminates prematurely #40263
Comments
def g(x, y):
for i in x:
for j in y:
yield i, j
r2 = (0, 1)
[e for e in g(r2, g(r2, r2))] Expected result: [(0, (0, 0)), (0, (0, 1)), (0, (1, 0)), (0, (1, 1)), Actual result: [(0, (0, 0)), (0, (0, 1)), (0, (1, 0)), (0, (1, 1))] |
Logged In: YES Trying again to get the indentation correct: def g(x, y):
for i in x:
for j in y:
yield i, j |
Logged In: YES Um. I think the answer to this is "generators are not |
Logged In: YES Too bad. What exactly is the restriction? For example: def primes():
yield 2
for n in count(3):
for p in primes():
if p > sqrt(n):
yield n
break
if n % p == 0:
break |
Logged In: YES Well, it's impossible in general. You'd have to store any What about things like: def foo(aList):
while aList:
yield aList.pop() ? |
Logged In: YES Python functions can be called recursively Generator functions also seem to be supported, There is a restriction on a generator object But this is definitely not a case of that If there is some other restriction, I think it ought This smells like a bug to me, though. |
Logged In: YES Your issue is that you only create a total of two generator The difference is the same as between r2 and iter(r2). If it = iter(r2)
for x in it: print x
for x in it: print x the second loop will be empty beause the first loop has Using the same iterator on several 'for' loops is useful, |
Logged In: YES Marking this as invalid and closing. Sorry, non-re-iterability is documented fact of life in the The work arounds include making the inner generator into a def g(x, y): |
Logged In: YES OK. I can get the semantics I want using the following: def g(x, y):
for i in x:
for j in y:
yield i, j
g = restartable(g) where I have defined: class restartable:
def __init__(self, genfn):
self.genfn = genfn
def __call__(self, *args):
return restartable_generator(self.genfn, *args)
class restartable_generator:
def __init__(self, genfn, *args):
self.genfn = genfn
self.args = args
def __iter__(self):
return self.genfn(*self.args) |
Logged In: YES Unless you are generating a very long list, you worked too >>> def g(x, y):
... y = list(y)
... for i in x:
... for j in y:
... yield i, j
...
>>> r2 = (0, 1)
>>> [e for e in g(r2, g(r2, r2))]
[(0, (0, 0)), (0, (0, 1)), (0, (1, 0)), (0, (1, 1)),
(1, (0, 0)), (1, (0, 1)), (1, (1, 0)), (1, (1, 1))] |
Note: these values reflect the state of the issue at the time it was migrated and might not reflect the current state.
Show more details
GitHub fields:
bugs.python.org fields:
The text was updated successfully, but these errors were encountered: