pythongeneratornested-loops

Why this nested loop generator does not seem to be working?


I was trying this:

tuple(map(tuple, tuple(((x,y) for x in range(5)) for y in range(3))))

I got this:

(((0, 2), (1, 2), (2, 2), (3, 2), (4, 2)),
 ((0, 2), (1, 2), (2, 2), (3, 2), (4, 2)),
 ((0, 2), (1, 2), (2, 2), (3, 2), (4, 2)))

but I expect:

(((0, 0), (1, 0), (2, 0), (3, 0), (4, 0)), 
 ((0, 1), (1, 1), (2, 1), (3, 1), (4, 1)), 
 ((0, 2), (1, 2), (2, 2), (3, 2), (4, 2)))

Solution

  • You're forcing the evaluations in the wrong order. You're building a generator of generators, building a tuple out of the outer generator to build a tuple of generators, and then building tuples out of the inner generators.

    By the time you start working with the inner generators, the outer generator has finished iteration, so y is already 2, the value from the last iteration. This is the y value used the entire time you're iterating over the inner generators, so it's the y value used every time you evaluate (x, y).

    You need to call tuple on the inner generators as they're produced, to iterate over them and evaluate (x, y) before y changes:

    tuple(tuple((x, y) for x in range(5)) for y in range(3))