Would somebody please explain the behavior of a nested loop using generators? Here is an example.
a = (x for x in range(3))
b = (x for x in range(2))
for i in a:
for j in b:
print (i,j)
The outer loop is not evaluated after the first iteration for some reason. The result is,
(0, 0)
(0, 1)
On the other hand, if generators are directly inserted into the loops, it does what I expect.
for i in (x for x in range(3)):
for j in (x for x in range(2)):
print (i,j)
giving all 3x2 pairs.
(0, 0)
(0, 1)
(1, 0)
(1, 1)
(2, 0)
(2, 1)
It's because the b
generator is exhausted during the first iteration of the outer for loop. Subsequent iterations will in effect have an empty inner loop (like for x in ()
) so what's inside is never executed. This gives the false impression that it's the outer loop that fails, somehow.
Your second example works because there the inner generator is created anew for each outer loop. To fix your first example, you have to do the same:
a = (x for x in range(3))
for i in a:
b = (x for x in range(2))
for j in b:
print (i,j)
@lazyr has answered this brilliantly, but I would point out for reference that when using nested generators it's worth knowing about itertools.product
...
for i, j in itertools.product(range(3), range(2)):
print (i, j)
or (if you have lots of vals):
for vals in itertools.product(range(45), range(12), range(3)):
print (sum(vals))
It's (IMHO) readable and avoids excessive indentation.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With