Commit 7d59c821 authored by Raymond Hettinger's avatar Raymond Hettinger

Add an example to address a common question of how to split iterators.

parent d915bf9b
...@@ -321,13 +321,15 @@ Samuele ...@@ -321,13 +321,15 @@ Samuele
\end{verbatim} \end{verbatim}
This section has further examples of how itertools can be combined. This section shows how itertools can be combined to create other more
Note that \function{enumerate()} and \method{iteritems()} already powerful itertools. Note that \function{enumerate()} and \method{iteritems()}
have highly efficient implementations in Python. They are only already have efficient implementations in Python. They are only included here
included here to illustrate how higher level tools can be created to illustrate how higher level tools can be created from building blocks.
from building blocks.
\begin{verbatim} \begin{verbatim}
def take(n, seq):
return list(islice(seq, n))
def enumerate(iterable): def enumerate(iterable):
return izip(count(), iterable) return izip(count(), iterable)
...@@ -380,7 +382,18 @@ def window(seq, n=2): ...@@ -380,7 +382,18 @@ def window(seq, n=2):
result = result[1:] + (elem,) result = result[1:] + (elem,)
yield result yield result
def take(n, seq): def tee(iterable):
return list(islice(seq, n)) "Return two independent iterators from a single iterable"
def gen(next, data={}, cnt=[0]):
dpop = data.pop
for i in count():
if i == cnt[0]:
item = data[i] = next()
cnt[0] += 1
else:
item = dpop(i)
yield item
next = iter(iterable).next
return (gen(next), gen(next))
\end{verbatim} \end{verbatim}
...@@ -487,6 +487,9 @@ Martin ...@@ -487,6 +487,9 @@ Martin
Walter Walter
Samuele Samuele
>>> def take(n, seq):
... return list(islice(seq, n))
>>> def enumerate(iterable): >>> def enumerate(iterable):
... return izip(count(), iterable) ... return izip(count(), iterable)
...@@ -539,12 +542,26 @@ Samuele ...@@ -539,12 +542,26 @@ Samuele
... result = result[1:] + (elem,) ... result = result[1:] + (elem,)
... yield result ... yield result
>>> def take(n, seq): >>> def tee(iterable):
... return list(islice(seq, n)) ... "Return two independent iterators from a single iterable"
... def gen(next, data={}, cnt=[0]):
... dpop = data.pop
... for i in count():
... if i == cnt[0]:
... item = data[i] = next()
... cnt[0] += 1
... else:
... item = dpop(i)
... yield item
... next = iter(iterable).next
... return (gen(next), gen(next))
This is not part of the examples but it tests to make sure the definitions This is not part of the examples but it tests to make sure the definitions
perform as purported. perform as purported.
>>> take(10, count())
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
>>> list(enumerate('abc')) >>> list(enumerate('abc'))
[(0, 'a'), (1, 'b'), (2, 'c')] [(0, 'a'), (1, 'b'), (2, 'c')]
...@@ -590,8 +607,17 @@ False ...@@ -590,8 +607,17 @@ False
>>> dotproduct([1,2,3], [4,5,6]) >>> dotproduct([1,2,3], [4,5,6])
32 32
>>> take(10, count()) >>> def irange(start, stop):
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9] ... for i in range(start, stop):
... yield i
>>> x, y = tee(irange(2,10))
>>> list(x), list(y)
([2, 3, 4, 5, 6, 7, 8, 9], [2, 3, 4, 5, 6, 7, 8, 9])
>>> x, y = tee(irange(2,10))
>>> zip(x, y)
[(2, 2), (3, 3), (4, 4), (5, 5), (6, 6), (7, 7), (8, 8), (9, 9)]
""" """
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment