bpo-31270: Modification of Pr 3200 (#3427)
authorRaymond Hettinger <rhettinger@users.noreply.github.com>
Thu, 7 Sep 2017 21:01:44 +0000 (14:01 -0700)
committerGitHub <noreply@github.com>
Thu, 7 Sep 2017 21:01:44 +0000 (14:01 -0700)
* bpo-31270: Simplify documentation of itertools.zip_longest

* Use repeat(). Track num_active.

Doc/library/itertools.rst

index b0d0a8c8c8ccd7f346f403ec6ab9eef9798eb2a8..c989e464200d8ba791c4f983c22c7fd1a15ba64e 100644 (file)
@@ -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