From 47a128d5ce445361945ec0a5d9df023a5b968ea9 Mon Sep 17 00:00:00 2001 From: Raymond Hettinger Date: Tue, 12 Mar 2024 23:59:28 -0500 Subject: [PATCH 1/7] Spell-out iterable --- Doc/library/itertools.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Doc/library/itertools.rst b/Doc/library/itertools.rst index 36e555d37d45de..7712d438d005c8 100644 --- a/Doc/library/itertools.rst +++ b/Doc/library/itertools.rst @@ -997,10 +997,10 @@ The following recipes have a more mathematical flavor: s = list(iterable) return chain.from_iterable(combinations(s, r) for r in range(len(s)+1)) - def sum_of_squares(it): + def sum_of_squares(iterable): "Add up the squares of the input values." # sum_of_squares([10, 20, 30]) --> 1400 - return math.sumprod(*tee(it)) + return math.sumprod(*tee(iterable)) def reshape(matrix, cols): "Reshape a 2-D matrix to have a given number of columns." From 3d9179fd36380f5e95d7380846bb71894fc5bd84 Mon Sep 17 00:00:00 2001 From: Raymond Hettinger Date: Wed, 13 Mar 2024 00:04:00 -0500 Subject: [PATCH 2/7] Spell-out prime --- Doc/library/itertools.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Doc/library/itertools.rst b/Doc/library/itertools.rst index 7712d438d005c8..52d6f3d166aa1e 100644 --- a/Doc/library/itertools.rst +++ b/Doc/library/itertools.rst @@ -1104,8 +1104,8 @@ The following recipes have a more mathematical flavor: "Count of natural numbers up to n that are coprime to n." # https://mathworld.wolfram.com/TotientFunction.html # totient(12) --> 4 because len([1, 5, 7, 11]) == 4 - for p in unique_justseen(factor(n)): - n -= n // p + for prime in unique_justseen(factor(n)): + n -= n // prime return n From bb6b1dcc2b7a7f03995c187fde53ef6a0cb9522c Mon Sep 17 00:00:00 2001 From: Raymond Hettinger Date: Wed, 13 Mar 2024 00:06:23 -0500 Subject: [PATCH 3/7] Replaces "args" with the more descriptive "iterators". --- Doc/library/itertools.rst | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Doc/library/itertools.rst b/Doc/library/itertools.rst index 52d6f3d166aa1e..3a7918129dfbf5 100644 --- a/Doc/library/itertools.rst +++ b/Doc/library/itertools.rst @@ -932,14 +932,14 @@ which incur interpreter overhead. # 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 + iterators = [iter(iterable)] * n match incomplete: case 'fill': - return zip_longest(*args, fillvalue=fillvalue) + return zip_longest(*iterators, fillvalue=fillvalue) case 'strict': - return zip(*args, strict=True) + return zip(*iterators, strict=True) case 'ignore': - return zip(*args) + return zip(*iterators) case _: raise ValueError('Expected fill, strict, or ignore') From 909da2f041503c04b385161e3c9abe4655690bf1 Mon Sep 17 00:00:00 2001 From: Raymond Hettinger Date: Wed, 13 Mar 2024 01:32:21 -0500 Subject: [PATCH 4/7] Revert "Spell-out prime" This reverts commit 3d9179fd36380f5e95d7380846bb71894fc5bd84. --- Doc/library/itertools.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Doc/library/itertools.rst b/Doc/library/itertools.rst index 3a7918129dfbf5..28c857078721e3 100644 --- a/Doc/library/itertools.rst +++ b/Doc/library/itertools.rst @@ -1104,8 +1104,8 @@ The following recipes have a more mathematical flavor: "Count of natural numbers up to n that are coprime to n." # https://mathworld.wolfram.com/TotientFunction.html # totient(12) --> 4 because len([1, 5, 7, 11]) == 4 - for prime in unique_justseen(factor(n)): - n -= n // prime + for p in unique_justseen(factor(n)): + n -= n // p return n From a13ca8d29350c6df5bf2a03ca49ae185410b82e9 Mon Sep 17 00:00:00 2001 From: Raymond Hettinger Date: Wed, 13 Mar 2024 01:41:27 -0500 Subject: [PATCH 5/7] More idiomatic and modern code for roundrobin(). --- Doc/library/itertools.rst | 19 ++++++++----------- 1 file changed, 8 insertions(+), 11 deletions(-) diff --git a/Doc/library/itertools.rst b/Doc/library/itertools.rst index 28c857078721e3..dbf3e4027e4b18 100644 --- a/Doc/library/itertools.rst +++ b/Doc/library/itertools.rst @@ -946,17 +946,11 @@ which incur interpreter overhead. def roundrobin(*iterables): "Visit input iterables in a cycle until each is exhausted." # roundrobin('ABC', 'D', 'EF') --> A D E B F C - # Recipe credited to George Sakkis - num_active = len(iterables) - nexts = cycle(iter(it).__next__ for it in iterables) - while num_active: - try: - for next in nexts: - yield next() - except StopIteration: - # Remove the iterator we just exhausted from the cycle. - num_active -= 1 - nexts = cycle(islice(nexts, num_active)) + # Algorithm credited to George Sakkis + iterators = cycle(map(iter, iterables)) + for cutoff in reversed(range(len(iterables))): + yield from map(next, iterators) + iterators = cycle(islice(iterators, cutoff)) def partition(predicate, iterable): """Partition entries into false entries and true entries. @@ -1570,6 +1564,9 @@ The following recipes have a more mathematical flavor: >>> list(roundrobin('abc', 'd', 'ef')) ['a', 'd', 'e', 'b', 'f', 'c'] + >>> ranges = [range(5, 1000), range(4, 3000), range(0), range(3, 2000), range(2, 5000), range(1, 3500)] + >>> collections.Counter(roundrobin(ranges)) == collections.Counter(ranges) + True >>> def is_odd(x): ... return x % 2 == 1 From 2486b78353b527377ab77fdf1dcd7e55189f5ec4 Mon Sep 17 00:00:00 2001 From: Raymond Hettinger Date: Wed, 13 Mar 2024 01:57:31 -0500 Subject: [PATCH 6/7] Put cycle() object creation in one place. --- Doc/library/itertools.rst | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Doc/library/itertools.rst b/Doc/library/itertools.rst index dbf3e4027e4b18..290b6ed350d754 100644 --- a/Doc/library/itertools.rst +++ b/Doc/library/itertools.rst @@ -947,10 +947,10 @@ which incur interpreter overhead. "Visit input iterables in a cycle until each is exhausted." # roundrobin('ABC', 'D', 'EF') --> A D E B F C # Algorithm credited to George Sakkis - iterators = cycle(map(iter, iterables)) - for cutoff in reversed(range(len(iterables))): + iterators = map(iter, iterables) + for num_active in reversed(range(len(iterables) + 1)): + iterators = cycle(islice(iterators, num_active)) yield from map(next, iterators) - iterators = cycle(islice(iterators, cutoff)) def partition(predicate, iterable): """Partition entries into false entries and true entries. From 240bf6725a311f19237a53138422fb0d8ad1342a Mon Sep 17 00:00:00 2001 From: Raymond Hettinger Date: Wed, 13 Mar 2024 02:02:16 -0500 Subject: [PATCH 7/7] Remove reversed() --- Doc/library/itertools.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Doc/library/itertools.rst b/Doc/library/itertools.rst index 290b6ed350d754..26d5cdaff8c14f 100644 --- a/Doc/library/itertools.rst +++ b/Doc/library/itertools.rst @@ -948,7 +948,7 @@ which incur interpreter overhead. # roundrobin('ABC', 'D', 'EF') --> A D E B F C # Algorithm credited to George Sakkis iterators = map(iter, iterables) - for num_active in reversed(range(len(iterables) + 1)): + for num_active in range(len(iterables), 0, -1): iterators = cycle(islice(iterators, num_active)) yield from map(next, iterators)