S
Steven D'Aprano
Suppose I have an iterator that yields tuples of N items (a, b, ... n).
I want to split this into N independent iterators:
iter1 -> a, a2, a3, ...
iter2 -> b, b2, b3, ...
....
iterN -> n, n2, n3, ...
The iterator may be infinite, or at least too big to collect in a list.
My first attempt was this:
def split(iterable, n):
iterators = []
for i, iterator in enumerate(itertools.tee(iterable, n)):
iterators.append((t for t in iterator))
return tuple(iterators)
But it doesn't work, as all the iterators see the same values:
I tried changing the t to use operator.itergetter instead, but no
luck. Finally I got this:
def split(iterable, n):
iterators = []
for i, iterator in enumerate(itertools.tee(iterable, n)):
f = lambda it, i=i: (t for t in it)
iterators.append(f(iterator))
return tuple(iterators)
which seems to work:
Is this the right approach, or have I missed something obvious?
I want to split this into N independent iterators:
iter1 -> a, a2, a3, ...
iter2 -> b, b2, b3, ...
....
iterN -> n, n2, n3, ...
The iterator may be infinite, or at least too big to collect in a list.
My first attempt was this:
def split(iterable, n):
iterators = []
for i, iterator in enumerate(itertools.tee(iterable, n)):
iterators.append((t for t in iterator))
return tuple(iterators)
But it doesn't work, as all the iterators see the same values:
([3, 6, 9], [3, 6, 9], [3, 6, 9])data = [(1,2,3), (4,5,6), (7,8,9)]
a, b, c = split(data, 3)
list(a), list(b), list(c)
I tried changing the t to use operator.itergetter instead, but no
luck. Finally I got this:
def split(iterable, n):
iterators = []
for i, iterator in enumerate(itertools.tee(iterable, n)):
f = lambda it, i=i: (t for t in it)
iterators.append(f(iterator))
return tuple(iterators)
which seems to work:
([1, 4, 7], [2, 5, 8], [3, 6, 9])data = [(1,2,3), (4,5,6), (7,8,9)]
a, b, c = split(data, 3)
list(a), list(b), list(c)
Is this the right approach, or have I missed something obvious?