Just playing around with various ways of generating prime numbers. The focus is on readability, not speed.
In [1]:
from itertools import islice, count
In [2]:
known_good_primes = [2, 3, 5, 7, 11, 13, 17,19, 23, 29]
In [3]:
def check():
assert list(islice(gen_primes(), len(known_good_primes))) == known_good_primes
In [4]:
def gen_primes(start=2):
for p in count(start):
for divisor in range(2, p):
if p % divisor == 0:
break
else:
yield p
In [5]:
check()
In [6]:
def is_divisible(p):
return any(p % divisor == 0 for divisor in range(2, p))
def gen_primes(start=2):
return (
p
for p in count(start)
if not is_divisible(p)
)
In [7]:
check()
In [8]:
def is_prime(p):
return all(p % divisor != 0 for divisor in range(2, p))
def gen_primes(start=2):
return (p for p in count(start) if is_prime(p))
In [9]:
check()
This is pretty readable.
In [10]:
def is_prime(p):
return all(p % divisor != 0 for divisor in range(2, p))
def gen_primes(start=2):
return filter(is_prime, count(start))
In [11]:
check()
Do it all in one expression. It works, but is ugly and hard to read.
In [12]:
def gen_primes(start=2):
return filter(
lambda p: all(p % divisor != 0 for divisor in range(2, p)),
count(start)
)
In [13]:
check()