]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
Add more itertool recipes (GH-28165)
authorRaymond Hettinger <rhettinger@users.noreply.github.com>
Tue, 7 Sep 2021 17:29:00 +0000 (12:29 -0500)
committerGitHub <noreply@github.com>
Tue, 7 Sep 2021 17:29:00 +0000 (12:29 -0500)
Doc/library/itertools.rst
Lib/test/test_itertools.py

index 254e055bd9eb439c38ce9567515ecc5acc3a82f6..bf60a0cee795f40cebc08cf0406daf491b9cd626 100644 (file)
@@ -492,6 +492,8 @@ loops that truncate the stream.
             next(b, None)
             return zip(a, b)
 
+   .. versionadded:: 3.10
+
 
 .. function:: permutations(iterable, r=None)
 
@@ -812,11 +814,27 @@ which incur interpreter overhead.
        return starmap(func, repeat(args, times))
 
    def grouper(iterable, n, fillvalue=None):
-       "Collect data into fixed-length chunks or blocks"
-       # grouper('ABCDEFG', 3, 'x') --> ABC DEF Gxx"
+       "Collect data into non-overlapping fixed-length chunks or blocks"
+       # grouper('ABCDEFG', 3, 'x') --> ABC DEF Gxx
        args = [iter(iterable)] * n
        return zip_longest(*args, fillvalue=fillvalue)
 
+   def triplewise(iterable):
+       "Return overlapping triplets from an iterable"
+       # pairwise('ABCDEFG') -> ABC BCD CDE DEF EFG
+       for (a, _), (b, c) in pairwise(pairwise(iterable)):
+           yield a, b, c
+
+   def sliding_window(iterable, n):
+       # sliding_window('ABCDEFG', 4) -> ABCD BCDE CDEF DEFG
+       it = iter(iterable)
+       window = deque(islice(it, n), maxlen=n)
+       if len(window) == n:
+           yield tuple(window)
+       for x in it:
+           window.append(x)
+           yield tuple(window)
+
    def roundrobin(*iterables):
        "roundrobin('ABC', 'D', 'EF') --> A D E B F C"
        # Recipe credited to George Sakkis
index 0cf7eaf25a05089aa3189c4b897cf0b0b281b909..aa81076f32d001b0b8e9eb1b974c957fb18bf453 100644 (file)
@@ -2394,6 +2394,23 @@ Samuele
 ...     else:
 ...         return starmap(func, repeat(args, times))
 
+>>> def triplewise(iterable):
+...     "Return overlapping triplets from an iterable"
+...     # pairwise('ABCDEFG') -> ABC BCD CDE DEF EFG
+...     for (a, _), (b, c) in pairwise(pairwise(iterable)):
+...         yield a, b, c
+
+>>> import collections
+>>> def sliding_window(iterable, n):
+...     # sliding_window('ABCDEFG', 4) -> ABCD BCDE CDEF DEFG
+...     it = iter(iterable)
+...     window = collections.deque(islice(it, n), maxlen=n)
+...     if len(window) == n:
+...         yield tuple(window)
+...     for x in it:
+...         window.append(x)
+...         yield tuple(window)
+
 >>> def grouper(n, iterable, fillvalue=None):
 ...     "grouper(3, 'ABCDEFG', 'x') --> ABC DEF Gxx"
 ...     args = [iter(iterable)] * n
@@ -2570,6 +2587,12 @@ True
 >>> list(grouper(3, 'abcdefg', 'x'))
 [('a', 'b', 'c'), ('d', 'e', 'f'), ('g', 'x', 'x')]
 
+>>> list(triplewise('ABCDEFG'))
+[('A', 'B', 'C'), ('B', 'C', 'D'), ('C', 'D', 'E'), ('D', 'E', 'F'), ('E', 'F', 'G')]
+
+>>> list(sliding_window('ABCDEFG', 4))
+[('A', 'B', 'C', 'D'), ('B', 'C', 'D', 'E'), ('C', 'D', 'E', 'F'), ('D', 'E', 'F', 'G')]
+
 >>> list(roundrobin('abc', 'd', 'ef'))
 ['a', 'd', 'e', 'b', 'f', 'c']