From 540439a62976c0f5fcdfc7bfad214e33f8df691e Mon Sep 17 00:00:00 2001 From: Raphael Michel Date: Thu, 24 Aug 2017 18:04:01 +0200 Subject: [PATCH] bpo-31270: Simplify documentation of itertools.zip_longest --- Doc/library/itertools.rst | 40 +++++++++++++++++++-------------------- 1 file changed, 20 insertions(+), 20 deletions(-) diff --git a/Doc/library/itertools.rst b/Doc/library/itertools.rst index b0d0a8c8c8ccd7..01cdd3f1f5cd32 100644 --- a/Doc/library/itertools.rst +++ b/Doc/library/itertools.rst @@ -630,26 +630,26 @@ 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): - # 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 + def zip_longest(*args, **kwds): + # zip_longest('ABCD', 'xy', fillvalue='-') --> Ax By C- D- + fillvalue = kwds.get('fillvalue') + iterators = [iter(it) for it in args] + + while True: + exhausted = 0 + values = [] + + for it in iterators: + try: + values.append(next(it)) + except StopIteration: + values.append(fillvalue) + exhausted += 1 + + if exhausted < len(args): + yield tuple(values) + else: + break 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