return a list of all primes numbers up to max listslowprimes0 listslowprimes1 listslowprimes10 listslowprimes25 2 3 5 7 11 13 17 19 23 listslowprimes11 2 3 5 7 11 listslowprimes33 2 3 5 7 11 13 17 19 23 29 31 listslowprimes10001 997 return a list of all primes numbers up to max listprimes0 listprimes1 listprimes10 listprimes25 2 3 5 7 11 13 17 19 23 listprimes11 2 3 5 7 11 listprimes33 2 3 5 7 11 13 17 19 23 29 31 listprimes10001 997 only need to check for factors up to sqrti return a list of all primes numbers up to max listfastprimes0 listfastprimes1 listfastprimes10 listfastprimes25 2 3 5 7 11 13 17 19 23 listfastprimes11 2 3 5 7 11 listfastprimes33 2 3 5 7 11 13 17 19 23 29 31 listfastprimes10001 997 it s useless to test even numbers as they will not be prime as we removed the even numbers we don t need them now let s benchmark our functions sidebyside return a list of all primes numbers up to max list slow_primes 0 list slow_primes 1 list slow_primes 10 list slow_primes 25 2 3 5 7 11 13 17 19 23 list slow_primes 11 2 3 5 7 11 list slow_primes 33 2 3 5 7 11 13 17 19 23 29 31 list slow_primes 1000 1 997 return a list of all primes numbers up to max list primes 0 list primes 1 list primes 10 list primes 25 2 3 5 7 11 13 17 19 23 list primes 11 2 3 5 7 11 list primes 33 2 3 5 7 11 13 17 19 23 29 31 list primes 1000 1 997 only need to check for factors up to sqrt i return a list of all primes numbers up to max list fast_primes 0 list fast_primes 1 list fast_primes 10 list fast_primes 25 2 3 5 7 11 13 17 19 23 list fast_primes 11 2 3 5 7 11 list fast_primes 33 2 3 5 7 11 13 17 19 23 29 31 list fast_primes 1000 1 997 it s useless to test even numbers as they will not be prime because 2 will not be tested it s necessary to yield it now as we removed the even numbers we don t need them now let s benchmark our functions side by side
import math
from collections.abc import Generator


def slow_primes(max_n: int) -> Generator[int, None, None]:
    
    numbers: Generator = (i for i in range(1, (max_n + 1)))
    for i in (n for n in numbers if n > 1):
        for j in range(2, i):
            if (i % j) == 0:
                break
        else:
            yield i


def primes(max_n: int) -> Generator[int, None, None]:
    
    numbers: Generator = (i for i in range(1, (max_n + 1)))
    for i in (n for n in numbers if n > 1):
        
        bound = int(math.sqrt(i)) + 1
        for j in range(2, bound):
            if (i % j) == 0:
                break
        else:
            yield i


def fast_primes(max_n: int) -> Generator[int, None, None]:
    
    numbers: Generator = (i for i in range(1, (max_n + 1), 2))
    
    if max_n > 2:
        yield 2  
    for i in (n for n in numbers if n > 1):
        bound = int(math.sqrt(i)) + 1
        for j in range(3, bound, 2):
            
            if (i % j) == 0:
                break
        else:
            yield i


def benchmark():
    
    from timeit import timeit

    setup = "from __main__ import slow_primes, primes, fast_primes"
    print(timeit("slow_primes(1_000_000_000_000)", setup=setup, number=1_000_000))
    print(timeit("primes(1_000_000_000_000)", setup=setup, number=1_000_000))
    print(timeit("fast_primes(1_000_000_000_000)", setup=setup, number=1_000_000))


if __name__ == "__main__":
    number = int(input("Calculate primes up to:\n>> ").strip())
    for ret in primes(number):
        print(ret)
    benchmark()