diff options
Diffstat (limited to 'Doc/library/itertools.rst')
-rw-r--r-- | Doc/library/itertools.rst | 37 |
1 files changed, 18 insertions, 19 deletions
diff --git a/Doc/library/itertools.rst b/Doc/library/itertools.rst index b0d0a8c..c989e46 100644 --- a/Doc/library/itertools.rst +++ b/Doc/library/itertools.rst @@ -630,26 +630,25 @@ loops that truncate the stream. iterables are of uneven length, missing values are filled-in with *fillvalue*. Iteration continues until the longest iterable is exhausted. Roughly equivalent to:: - class ZipExhausted(Exception): - pass - - def zip_longest(*args, **kwds): + def zip_longest(*args, fillvalue=None): # zip_longest('ABCD', 'xy', fillvalue='-') --> Ax By C- D- - fillvalue = kwds.get('fillvalue') - counter = len(args) - 1 - def sentinel(): - nonlocal counter - if not counter: - raise ZipExhausted - counter -= 1 - yield fillvalue - fillers = repeat(fillvalue) - iterators = [chain(it, sentinel(), fillers) for it in args] - try: - while iterators: - yield tuple(map(next, iterators)) - except ZipExhausted: - pass + iterators = [iter(it) for it in args] + num_active = len(iterators) + if not num_active: + return + while True: + values = [] + for i, it in enumerate(iterators): + try: + value = next(it) + except StopIteration: + num_active -= 1 + if not num_active: + return + iterators[i] = repeat(fillvalue) + value = fillvalue + values.append(value) + yield tuple(values) If one of the iterables is potentially infinite, then the :func:`zip_longest` function should be wrapped with something that limits the number of calls |