Imagine what happens if the last number in range(3, int(n**0.5), 2)
is not an integer divisor of n
:
if n % x ==0:
prime = False # not this
else:
prime = True # this
So even if all previous checks evaluated False
, you call n
a prime. The minimal change to your code to fix this is:
prime = prime and True # or 'prime &= True'
So if prime
is already False
, it remains False
.
However, bear in mind that, for primality, if any of those checks is False
n
is not prime. You can use this and Python's and
and all
(which are evaluated lazily, i.e. don't keep checking once finding a False
) to implement much more efficiently:
def rand_prime():
while True:
p = randint(10000, 100000)
if (r % 2 != 0 and
all(p % n != 0 for n in range(3, int(((p ** 0.5) + 1), 2))):
return p
For even better performance, note that randrange
incorporates a step
argument, just like range
, so you can skip all of the even numbers (which definitely aren't prime!):
def rand_prime():
while True:
p = randrange(10001, 100000, 2)
if all(p % n != 0 for n in range(3, int((p ** 0.5) + 1), 2)):
return p
Note: sqrt(n)
(from math
) is, in my opinion, a little clearer to other, less-technical readers than n ** 0.5
(although it may or may not be more efficient).
for
loop, you're ignoring what the earlier iterations told you by settingprime = False
orprime = True
without considering whatprime
used to be. – Gage