mirror of
https://github.com/python/cpython.git
synced 2025-11-12 15:09:14 +00:00
Guarantee evaluation order for izip(). Document its creative uses and its limitations.
This commit is contained in:
parent
1818ed705b
commit
a531e5b84c
1 changed files with 23 additions and 1 deletions
|
|
@ -276,13 +276,30 @@ by functions or loops that truncate the stream.
|
||||||
def izip(*iterables):
|
def izip(*iterables):
|
||||||
iterables = map(iter, iterables)
|
iterables = map(iter, iterables)
|
||||||
while iterables:
|
while iterables:
|
||||||
result = [i.next() for i in iterables]
|
result = [it.next() for it in iterables]
|
||||||
yield tuple(result)
|
yield tuple(result)
|
||||||
\end{verbatim}
|
\end{verbatim}
|
||||||
|
|
||||||
\versionchanged[When no iterables are specified, returns a zero length
|
\versionchanged[When no iterables are specified, returns a zero length
|
||||||
iterator instead of raising a \exception{TypeError}
|
iterator instead of raising a \exception{TypeError}
|
||||||
exception]{2.4}
|
exception]{2.4}
|
||||||
|
|
||||||
|
Note, the left-to-right evaluation order of the iterables is guaranteed.
|
||||||
|
This makes possible an idiom for clustering a data series into n-length
|
||||||
|
groups using \samp{izip(*[iter(s)]*n)}. For data that doesn't fit
|
||||||
|
n-length groups exactly, the last tuple can be pre-padded with fill
|
||||||
|
values using \samp{izip(*[chain(s, [None]*(n-1))]*n)}.
|
||||||
|
|
||||||
|
Note, when \function{izip()} is used with unequal length inputs, subsequent
|
||||||
|
iteration over the longer iterables cannot reliably be continued after
|
||||||
|
\function{izip()} terminates. Potentially, up to one entry will be missing
|
||||||
|
from each of the left-over iterables. This occurs because a value is fetched
|
||||||
|
from each iterator in-turn, but the process ends when one of the iterators
|
||||||
|
terminates. This leaves the last fetched values in limbo (they cannot be
|
||||||
|
returned in a final, incomplete tuple and they are cannot be pushed back
|
||||||
|
into the iterator for retrieval with \code{it.next()}). In general,
|
||||||
|
\function{izip()} should only be used with unequal length inputs when you
|
||||||
|
don't care about trailing, unmatched values from the longer iterables.
|
||||||
\end{funcdesc}
|
\end{funcdesc}
|
||||||
|
|
||||||
\begin{funcdesc}{repeat}{object\optional{, times}}
|
\begin{funcdesc}{repeat}{object\optional{, times}}
|
||||||
|
|
@ -518,4 +535,9 @@ def pairwise(iterable):
|
||||||
pass
|
pass
|
||||||
return izip(a, b)
|
return izip(a, b)
|
||||||
|
|
||||||
|
def grouper(n, iterable, padvalue=None):
|
||||||
|
"grouper(3, 'abcdefg', 'x') --> ('a','b','c'), ('d','e','f'), ('g','x','x')"
|
||||||
|
return izip(*[chain(iterable, repeat(padvalue, n-1))]*n)
|
||||||
|
|
||||||
|
|
||||||
\end{verbatim}
|
\end{verbatim}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue