summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRaymond Hettinger <rhettinger@users.noreply.github.com>2021-09-07 17:29:00 (GMT)
committerGitHub <noreply@github.com>2021-09-07 17:29:00 (GMT)
commit750368cbcd20393026f3bf695195f1a2cba490b5 (patch)
tree25c217a88b942eed7ad9fbee097f8faf1236597c
parentcc7c6801945c6a7373553b78bd899ce09681ec0a (diff)
downloadcpython-750368cbcd20393026f3bf695195f1a2cba490b5.zip
cpython-750368cbcd20393026f3bf695195f1a2cba490b5.tar.gz
cpython-750368cbcd20393026f3bf695195f1a2cba490b5.tar.bz2
Add more itertool recipes (GH-28165)
-rw-r--r--Doc/library/itertools.rst22
-rw-r--r--Lib/test/test_itertools.py23
2 files changed, 43 insertions, 2 deletions
diff --git a/Doc/library/itertools.rst b/Doc/library/itertools.rst
index 254e055..bf60a0c 100644
--- a/Doc/library/itertools.rst
+++ b/Doc/library/itertools.rst
@@ -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
diff --git a/Lib/test/test_itertools.py b/Lib/test/test_itertools.py
index 0cf7eaf..aa81076 100644
--- a/Lib/test/test_itertools.py
+++ b/Lib/test/test_itertools.py
@@ -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']