diff options
author | Raymond Hettinger <rhettinger@users.noreply.github.com> | 2022-10-15 17:43:58 (GMT) |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-10-15 17:43:58 (GMT) |
commit | f4370318d67f1f2f686c1c3a4b217ccc461d31e5 (patch) | |
tree | 04fb960286b12c8f20ec7587e9442c3b8f0551f5 /Doc/library | |
parent | 146f168fbf5b239158922f4defd494088c381525 (diff) | |
download | cpython-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.rst | 35 |
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] |