]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
Improve grouper() recipe to demonstrate all forms of zip() (GH-30837)
authorRaymond Hettinger <rhettinger@users.noreply.github.com>
Sun, 23 Jan 2022 20:31:10 +0000 (14:31 -0600)
committerGitHub <noreply@github.com>
Sun, 23 Jan 2022 20:31:10 +0000 (14:31 -0600)
Doc/library/itertools.rst
Lib/test/test_itertools.py

index 61d8b869711fa49b008c0ae6881697491d78b31c..34667561c3cfe760e05638da2ccef976718d9fe9 100644 (file)
@@ -813,11 +813,20 @@ which incur interpreter overhead.
            return starmap(func, repeat(args))
        return starmap(func, repeat(args, times))
 
-   def grouper(iterable, n, fillvalue=None):
+   def grouper(iterable, n, *, incomplete='fill', fillvalue=None):
        "Collect data into non-overlapping fixed-length chunks or blocks"
-       # grouper('ABCDEFG', 3, 'x') --> ABC DEF Gxx
+       # grouper('ABCDEFG', 3, fillvalue='x') --> ABC DEF Gxx
+       # grouper('ABCDEFG', 3, incomplete='strict') --> ABC DEF ValueError
+       # grouper('ABCDEFG', 3, incomplete='ignore') --> ABC DEF
        args = [iter(iterable)] * n
-       return zip_longest(*args, fillvalue=fillvalue)
+       if incomplete == 'fill':
+           return zip_longest(*args, fillvalue=fillvalue)
+       if incomplete == 'strict':
+           return zip(*args, strict=True)
+       if incomplete == 'ignore':
+           return zip(*args)
+       else:
+           raise ValueError('Expected fill, strict, or ignore')
 
    def triplewise(iterable):
        "Return overlapping triplets from an iterable"
index 808c32f7dd7ab397e31a0c3aee8540a4705aa62e..3043e8c404e6e4d4c703501ec59baeb0bacdcefd 100644 (file)
@@ -2436,6 +2436,21 @@ Samuele
 ...     else:
 ...         return starmap(func, repeat(args, times))
 
+>>> def grouper(iterable, n, *, incomplete='fill', fillvalue=None):
+...     "Collect data into non-overlapping fixed-length chunks or blocks"
+...     # grouper('ABCDEFG', 3, fillvalue='x') --> ABC DEF Gxx
+...     # grouper('ABCDEFG', 3, incomplete='strict') --> ABC DEF ValueError
+...     # grouper('ABCDEFG', 3, incomplete='ignore') --> ABC DEF
+...     args = [iter(iterable)] * n
+...     if incomplete == 'fill':
+...         return zip_longest(*args, fillvalue=fillvalue)
+...     if incomplete == 'strict':
+...         return zip(*args, strict=True)
+...     if incomplete == 'ignore':
+...         return zip(*args)
+...     else:
+...         raise ValueError('Expected fill, strict, or ignore')
+
 >>> def triplewise(iterable):
 ...     "Return overlapping triplets from an iterable"
 ...     # pairwise('ABCDEFG') -> ABC BCD CDE DEF EFG
@@ -2453,11 +2468,6 @@ Samuele
 ...         window.append(x)
 ...         yield tuple(window)
 
->>> def grouper(n, iterable, fillvalue=None):
-...     "grouper(3, 'ABCDEFG', 'x') --> ABC DEF Gxx"
-...     args = [iter(iterable)] * n
-...     return zip_longest(*args, fillvalue=fillvalue)
-
 >>> def roundrobin(*iterables):
 ...     "roundrobin('ABC', 'D', 'EF') --> A D E B F C"
 ...     # Recipe credited to George Sakkis
@@ -2626,9 +2636,22 @@ True
 >>> dotproduct([1,2,3], [4,5,6])
 32
 
->>> list(grouper(3, 'abcdefg', 'x'))
+>>> list(grouper('abcdefg', 3, fillvalue='x'))
 [('a', 'b', 'c'), ('d', 'e', 'f'), ('g', 'x', 'x')]
 
+>>> it = grouper('abcdefg', 3, incomplete='strict')
+>>> next(it)
+('a', 'b', 'c')
+>>> next(it)
+('d', 'e', 'f')
+>>> next(it)
+Traceback (most recent call last):
+  ...
+ValueError: zip() argument 2 is shorter than argument 1
+
+>>> list(grouper('abcdefg', n=3, incomplete='ignore'))
+[('a', 'b', 'c'), ('d', 'e', 'f')]
+
 >>> list(triplewise('ABCDEFG'))
 [('A', 'B', 'C'), ('B', 'C', 'D'), ('C', 'D', 'E'), ('D', 'E', 'F'), ('E', 'F', 'G')]