summaryrefslogtreecommitdiffstats
path: root/Doc/library
diff options
context:
space:
mode:
authorRaymond Hettinger <rhettinger@users.noreply.github.com>2022-10-15 17:43:58 (GMT)
committerGitHub <noreply@github.com>2022-10-15 17:43:58 (GMT)
commitf4370318d67f1f2f686c1c3a4b217ccc461d31e5 (patch)
tree04fb960286b12c8f20ec7587e9442c3b8f0551f5 /Doc/library
parent146f168fbf5b239158922f4defd494088c381525 (diff)
downloadcpython-f4370318d67f1f2f686c1c3a4b217ccc461d31e5.zip
cpython-f4370318d67f1f2f686c1c3a4b217ccc461d31e5.tar.gz
cpython-f4370318d67f1f2f686c1c3a4b217ccc461d31e5.tar.bz2
Faster sieve() recipe (#98287)
Diffstat (limited to 'Doc/library')
-rw-r--r--Doc/library/itertools.rst35
1 files changed, 27 insertions, 8 deletions
diff --git a/Doc/library/itertools.rst b/Doc/library/itertools.rst
index 6571114..056b078 100644
--- a/Doc/library/itertools.rst
+++ b/Doc/library/itertools.rst
@@ -809,15 +809,25 @@ which incur interpreter overhead.
for k in range(len(roots) + 1)
]
+ def iter_index(seq, value, start=0):
+ "Return indices where a value occurs in a sequence."
+ # iter_index('AABCADEAF', 'A') --> 0 1 4 7
+ i = start - 1
+ try:
+ while True:
+ yield (i := seq.index(value, i+1))
+ except ValueError:
+ pass
+
def sieve(n):
- "Primes less than n"
- # sieve(30) --> 2 3 5 7 11 13 17 19 23 29
- data = bytearray([1]) * n
- data[:2] = 0, 0
- limit = math.isqrt(n) + 1
- for p in compress(range(limit), data):
- data[p+p : n : p] = bytearray(len(range(p+p, n, p)))
- return compress(count(), data)
+ "Primes less than n"
+ # sieve(30) --> 2 3 5 7 11 13 17 19 23 29
+ data = bytearray([1]) * n
+ data[:2] = 0, 0
+ limit = math.isqrt(n) + 1
+ for p in compress(range(limit), data):
+ data[p*p : n : p] = bytearray(len(range(p*p, n, p)))
+ return iter_index(data, 1)
def flatten(list_of_lists):
"Flatten one level of nesting"
@@ -1170,6 +1180,15 @@ which incur interpreter overhead.
>>> all(factored(x) == expanded(x) for x in range(-10, 11))
True
+ >>> list(iter_index('AABCADEAF', 'A'))
+ [0, 1, 4, 7]
+ >>> list(iter_index('AABCADEAF', 'B'))
+ [2]
+ >>> list(iter_index('AABCADEAF', 'X'))
+ []
+ >>> list(iter_index('', 'X'))
+ []
+
>>> list(sieve(30))
[2, 3, 5, 7, 11, 13, 17, 19, 23, 29]
>>> small_primes = [2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97]