As others have said, Python sets generally don't maintain the order that the items were added in, so your loop condition may attempt to check divisibility by a prime that's too high for the current a
. You can use a set here, but you need to use a range (or some other way of producing trial factors in order) and then you can test if those trial factors are in the set of primes.
Here's a modified version of your code that does this. It prints the contents of the primes
set so you can see that they aren't ordered.
Note that I'm using a ** 0.5
to calculate the square root, rather than importing the sqrt
function from the math
library. Not only does this save doing an import
, operators tend to be faster than function calls.
primes = {2, 3}
def prime_checker(a):
if a in primes:
return True
for j in range(2, int(a ** 0.5) + 1):
if j in primes and a % j == 0:
return False
return True
hi = 200
for i in range (5, hi, 2):
if prime_checker(i):
primes.add(i)
print(len(primes))
print(primes)
print(*sorted(primes))
output
46
{2, 3, 131, 5, 7, 137, 11, 139, 13, 17, 19, 149, 23, 151, 29, 157, 31, 163, 37, 167, 41, 43, 173, 47, 179, 53, 181, 59, 61, 191, 193, 67, 197, 71, 199, 73, 79, 83, 89, 97, 101, 103, 107, 109, 113, 127}
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 101 103 107 109 113 127 131 137 139 149 151 157 163 167 173 179 181 191 193 197 199
The and
operator short-circuits, which means that in
if j in primes and a % j == 0:
if the j in primes
test fails then the a % j == 0
test won't be performed.
BTW, your prime_checker
function returns False
if a number fails the primality test, but it returns the default of None
if the test suceeds; that's a bit weird. :) Both False
and None
are treated as false-ish, i.e. if v is False
or None
then if a:
will fail.
The Python PEP-0008 style guide recommends that you do not explicitly test against True
or False
:
Don't compare boolean values to True or False using ==
.
Yes: if greeting:
No: if greeting == True:
Worse: if greeting is True:
i.e., instead of
if some_condition == False:
you should do
if not some_condition:
Of course, that won't work in your code because of the False
/ None
issue I mentioned above.
FWIW, there's some great prime-finding code at Fastest way to list all primes below N. That question is fairly old, so most of the answers are for Python 2, but they're easy enough to convert to Python 3.