After reading this answer which involves tee
in its code, I played a little bit, trying to generalize the solution presented there.
The task was to lazily "transpose" a list. That is, the list [xrange(1, 4), xrange(4, 7), xrange(7, 10)]
(in python 2.7) would have to become something which is similar to [xrange(1, 10, 3), xrange(2, 10, 3), xrange(3, 10, 3)]
.
I copy here the solution presented there:
def transpose(iterable_of_three_tuples):
teed = itertools.tee(iterable_of_three_tuples, 3)
return (e[0] for e in teed[0]), (e[1] for e in teed[1]), (e[2] for e in teed[2])
My generalization was about trying to do the same, where the 3
is a parameter. Since 3
is the length of the input generators, you can't guess it, and you have to add it as an argument for the function. Since some generators may be large or even infinite, I also think of this parameter as a limit, so we take the first n elements from each input generator only.
This is my code:
def transpose(zipped, n):
teed = tee(zipped, n)
return [(e[i] for e in teed[i]) for i in xrange(n)]
This is not working as expected, as the following example shows:
>>> data = [xrange(1, 4), xrange(4, 7), xrange(7, 10)]
>>> x, y, z = transpose(data, 3)
>>> x.next()
3
(I expected 1).
I guess this is something about the generator inside a list comprehension and leak of names, or lazy evaluation of i
or something similar... Can you tell what's wrong with my code and how it can be fixed?