Generalize the itertools.tee() recipe.
This commit is contained in:
parent
0654ccd1d2
commit
cf984cee93
|
@ -130,7 +130,7 @@ loops that truncate the stream.
|
||||||
return
|
return
|
||||||
indices = list(range(r))
|
indices = list(range(r))
|
||||||
yield tuple(pool[i] for i in indices)
|
yield tuple(pool[i] for i in indices)
|
||||||
while 1:
|
while True:
|
||||||
for i in reversed(range(r)):
|
for i in reversed(range(r)):
|
||||||
if indices[i] != i + n - r:
|
if indices[i] != i + n - r:
|
||||||
break
|
break
|
||||||
|
@ -178,7 +178,7 @@ loops that truncate the stream.
|
||||||
return
|
return
|
||||||
indices = [0] * r
|
indices = [0] * r
|
||||||
yield tuple(pool[i] for i in indices)
|
yield tuple(pool[i] for i in indices)
|
||||||
while 1:
|
while True:
|
||||||
for i in reversed(range(r)):
|
for i in reversed(range(r)):
|
||||||
if indices[i] != n - 1:
|
if indices[i] != n - 1:
|
||||||
break
|
break
|
||||||
|
@ -501,28 +501,28 @@ loops that truncate the stream.
|
||||||
|
|
||||||
.. function:: tee(iterable[, n=2])
|
.. function:: tee(iterable[, n=2])
|
||||||
|
|
||||||
Return *n* independent iterators from a single iterable. The case where ``n==2``
|
Return *n* independent iterators from a single iterable. Equivalent to::
|
||||||
is equivalent to::
|
|
||||||
|
|
||||||
def tee(iterable):
|
def tee(iterable, n=2):
|
||||||
def gen(next, data={}):
|
it = iter(iterable)
|
||||||
for i in count():
|
deques = [collections.deque() for i in range(n)]
|
||||||
if i in data:
|
def gen(mydeque):
|
||||||
yield data.pop(i)
|
while True:
|
||||||
else:
|
if not mydeque: # when the local deque is empty
|
||||||
data[i] = next()
|
newval = next(it) # fetch a new value and
|
||||||
yield data[i]
|
for d in deques: # load it to all the deques
|
||||||
it = iter(iterable)
|
d.append(newval)
|
||||||
return (gen(it.__next__), gen(it.__next__))
|
yield mydeque.popleft()
|
||||||
|
return tuple(gen(d) for d in deques)
|
||||||
|
|
||||||
Note, once :func:`tee` has made a split, the original *iterable* should not be
|
Once :func:`tee` has made a split, the original *iterable* should not be
|
||||||
used anywhere else; otherwise, the *iterable* could get advanced without the tee
|
used anywhere else; otherwise, the *iterable* could get advanced without
|
||||||
objects being informed.
|
the tee objects being informed.
|
||||||
|
|
||||||
Note, this member of the toolkit may require significant auxiliary storage
|
This itertool may require significant auxiliary storage (depending on how
|
||||||
(depending on how much temporary data needs to be stored). In general, if one
|
much temporary data needs to be stored). In general, if one iterator uses
|
||||||
iterator is going to use most or all of the data before the other iterator, it
|
most or all of the data before another iterator starts, it is faster to use
|
||||||
is faster to use :func:`list` instead of :func:`tee`.
|
:func:`list` instead of :func:`tee`.
|
||||||
|
|
||||||
|
|
||||||
.. function:: zip_longest(*iterables[, fillvalue])
|
.. function:: zip_longest(*iterables[, fillvalue])
|
||||||
|
|
Loading…
Reference in New Issue