Reputation: 97
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)))
Upvotes: 2
Views: 66
Reputation: 97
I used lambda because I think the argument of a function had the property of holding a value.
I do not understand the details of the detailed grammatical evaluation with difficulty, but I was able to successfully prepare a generator that generates a generator by doing the following.
root_gen = ((lambda t: ((t,y) for y in range(3)))(x) for x in range(5))
To evaluate, please use below:
tuple(map(tuple, root_gen))
The original idea is as follows:
# generate a sub generator
def sub_gen(x):
return ((x,y) for y in range(3))
# test
tuple(gen(1))
tuple(gen(2))
# make generator
root_gen = (gen(n) for n in range(5))
# evaluate
tuple(map(tuple(root_gen)))
Upvotes: 0
Reputation: 281748
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))
Upvotes: 2