Skip to content

Commit 66e1399

Browse files
authored
Minor readability/usability improvement to the recipes section (gh-143753)
1 parent 4766237 commit 66e1399

File tree

1 file changed

+23
-13
lines changed

1 file changed

+23
-13
lines changed

Doc/library/itertools.rst

Lines changed: 23 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -819,7 +819,7 @@ well as with the built-in itertools such as ``map()``, ``filter()``,
819819

820820
A secondary purpose of the recipes is to serve as an incubator. The
821821
``accumulate()``, ``compress()``, and ``pairwise()`` itertools started out as
822-
recipes. Currently, the ``sliding_window()``, ``iter_index()``, and ``sieve()``
822+
recipes. Currently, the ``sliding_window()``, ``derangements()``, and ``sieve()``
823823
recipes are being tested to see whether they prove their worth.
824824

825825
Substantially all of these recipes and many, many others can be installed from
@@ -838,11 +838,16 @@ and :term:`generators <generator>` which incur interpreter overhead.
838838

839839
.. testcode::
840840

841+
from itertools import (accumulate, batched, chain, combinations, compress,
842+
count, cycle, filterfalse, groupby, islice, permutations, product,
843+
repeat, starmap, tee, zip_longest)
841844
from collections import Counter, deque
842845
from contextlib import suppress
843846
from functools import reduce
844-
from math import comb, prod, sumprod, isqrt
845-
from operator import is_not, itemgetter, getitem, mul, neg
847+
from math import comb, isqrt, prod, sumprod
848+
from operator import getitem, is_not, itemgetter, mul, neg
849+
850+
# ==== Basic one liners ====
846851

847852
def take(n, iterable):
848853
"Return first n items of the iterable as a list."
@@ -899,15 +904,17 @@ and :term:`generators <generator>` which incur interpreter overhead.
899904

900905
def first_true(iterable, default=False, predicate=None):
901906
"Returns the first true value or the *default* if there is no true value."
902-
# first_true([a,b,c], x) → a or b or c or x
903-
# first_true([a,b], x, f) → a if f(a) else b if f(b) else x
907+
# first_true([a, b, c], x) → a or b or c or x
908+
# first_true([a, b], x, f) → a if f(a) else b if f(b) else x
904909
return next(filter(predicate, iterable), default)
905910

906911
def all_equal(iterable, key=None):
907912
"Returns True if all the elements are equal to each other."
908913
# all_equal('4٤௪౪໔', key=int) → True
909914
return len(take(2, groupby(iterable, key))) <= 1
910915

916+
# ==== Data pipelines ====
917+
911918
def unique_justseen(iterable, key=None):
912919
"Yield unique elements, preserving order. Remember only the element just seen."
913920
# unique_justseen('AAAABBBCCDAABBB') → A B C D A B
@@ -940,7 +947,7 @@ and :term:`generators <generator>` which incur interpreter overhead.
940947

941948
def sliding_window(iterable, n):
942949
"Collect data into overlapping fixed-length chunks or blocks."
943-
# sliding_window('ABCDEFG', 4) → ABCD BCDE CDEF DEFG
950+
# sliding_window('ABCDEFG', 3) → ABC BCD CDE DEF EFG
944951
iterator = iter(iterable)
945952
window = deque(islice(iterator, n - 1), maxlen=n)
946953
for x in iterator:
@@ -949,7 +956,7 @@ and :term:`generators <generator>` which incur interpreter overhead.
949956

950957
def grouper(iterable, n, *, incomplete='fill', fillvalue=None):
951958
"Collect data into non-overlapping fixed-length chunks or blocks."
952-
# grouper('ABCDEFG', 3, fillvalue='x') → ABC DEF Gxx
959+
# grouper('ABCDEFG', 3, fillvalue='x') → ABC DEF Gxx
953960
# grouper('ABCDEFG', 3, incomplete='strict') → ABC DEF ValueError
954961
# grouper('ABCDEFG', 3, incomplete='ignore') → ABC DEF
955962
iterators = [iter(iterable)] * n
@@ -1014,10 +1021,7 @@ and :term:`generators <generator>` which incur interpreter overhead.
10141021
while True:
10151022
yield function()
10161023

1017-
1018-
The following recipes have a more mathematical flavor:
1019-
1020-
.. testcode::
1024+
# ==== Mathematical operations ====
10211025

10221026
def multinomial(*counts):
10231027
"Number of distinct arrangements of a multiset."
@@ -1036,9 +1040,11 @@ The following recipes have a more mathematical flavor:
10361040
# sum_of_squares([10, 20, 30]) → 1400
10371041
return sumprod(*tee(iterable))
10381042
1043+
# ==== Matrix operations ====
1044+
10391045
def reshape(matrix, columns):
10401046
"Reshape a 2-D matrix to have a given number of columns."
1041-
# reshape([(0, 1), (2, 3), (4, 5)], 3) → (0, 1, 2), (3, 4, 5)
1047+
# reshape([(0, 1), (2, 3), (4, 5)], 3) → (0, 1, 2) (3, 4, 5)
10421048
return batched(chain.from_iterable(matrix), columns, strict=True)
10431049

10441050
def transpose(matrix):
@@ -1048,10 +1054,12 @@ The following recipes have a more mathematical flavor:
10481054
10491055
def matmul(m1, m2):
10501056
"Multiply two matrices."
1051-
# matmul([(7, 5), (3, 5)], [(2, 5), (7, 9)]) → (49, 80), (41, 60)
1057+
# matmul([(7, 5), (3, 5)], [(2, 5), (7, 9)]) → (49, 80) (41, 60)
10521058
n = len(m2[0])
10531059
return batched(starmap(sumprod, product(m1, transpose(m2))), n)
10541060

1061+
# ==== Polynomial arithmetic ====
1062+
10551063
def convolve(signal, kernel):
10561064
"""Discrete linear convolution of two iterables.
10571065
Equivalent to polynomial multiplication.
@@ -1106,6 +1114,8 @@ The following recipes have a more mathematical flavor:
11061114
powers = reversed(range(1, n))
11071115
return list(map(mul, coefficients, powers))
11081116

1117+
# ==== Number theory ====
1118+
11091119
def sieve(n):
11101120
"Primes less than n."
11111121
# sieve(30) → 2 3 5 7 11 13 17 19 23 29

0 commit comments

Comments
 (0)