patternpythonModerate
Is_prime check in Python: can this be more pythonic?
Viewed 0 times
thispythoniccanmoreis_primepythoncheck
Problem
I have the following function that checks if a number is prime:
Most of it are checks and calculations to save up time, to make it faster than a simple loop through a range.
Can it be written in a more pythonic way? Can it be improved in some way?
Any other feedback is welcome too.
def is_prime(n):
""" Is n prime? """
if n < 2:
return False
if n in (2, 3):
return True
if n % 2 == 0 or n % 3 == 0:
return False
limit = int(math.sqrt(n))
divisor = 5
while divisor <= limit:
if n % divisor == 0 or n % (divisor + 2) == 0:
return False
divisor += 6
return TrueMost of it are checks and calculations to save up time, to make it faster than a simple loop through a range.
Can it be written in a more pythonic way? Can it be improved in some way?
Any other feedback is welcome too.
Solution
Your code looks nice, seems to follow PEP 8 and has docstrings. I don't have much to say about it but here are a few changes to make it look more pythonic.
The
Then, this looks like a scenario where we could use
but it looks better (and makes more sense) to use
then, you can use the fact that non-zero numbers evaluates to True in a boolean context (and zero evaluates to False) :
Then, you could use the same kind of idea in the previous
This is pretty much all I have to say about the code. Now, I think it might be worth commenting the algorithm a bit more.
The
while loop can be rewritten using a for loop with range (or xrange).for divisor in xrange(5, 1+int(math.sqrt(n)), 6):
if n % divisor == 0 or n % (divisor + 2) == 0:
return False
return TrueThen, this looks like a scenario where we could use
all/any. The obvious way to convert the code above is :return not any(n % divisor == 0 or n % (divisor + 2) == 0 for divisor in xrange(5, int(math.sqrt(n))+1, 6))but it looks better (and makes more sense) to use
all with reversed conditions :return all(n % divisor != 0 and n % (divisor + 2) != 0 for divisor in xrange(5, int(math.sqrt(n))+1, 6))then, you can use the fact that non-zero numbers evaluates to True in a boolean context (and zero evaluates to False) :
return all(n % divisor and n % (divisor + 2) for divisor in xrange(5, int(math.sqrt(n))+1, 6))Then, you could use the same kind of idea in the previous
if then merge duplicated code :return n % 2 and n % 3 and all(n % divisor and n % (divisor + 2) for divisor in xrange(5, int(math.sqrt(n))+1, 6))This is pretty much all I have to say about the code. Now, I think it might be worth commenting the algorithm a bit more.
def is_prime(n):
""" Check if n (assumed to be an int) is a prime number. """
# Handle values up to 3
if n < 2:
return False
if n in (2, 3):
return True
# Handles bigger values : divisors for n have to be
# * multiples of 2
# * multiples of 3
# * of the form 5 + 6*i or 5 + 6*i + 2 (other cases already handled)
return n % 2 and n % 3 and all(n % divisor and n % (divisor + 2) for divisor in xrange(5, int(math.sqrt(n))+1, 6))Code Snippets
for divisor in xrange(5, 1+int(math.sqrt(n)), 6):
if n % divisor == 0 or n % (divisor + 2) == 0:
return False
return Truereturn not any(n % divisor == 0 or n % (divisor + 2) == 0 for divisor in xrange(5, int(math.sqrt(n))+1, 6))return all(n % divisor != 0 and n % (divisor + 2) != 0 for divisor in xrange(5, int(math.sqrt(n))+1, 6))return all(n % divisor and n % (divisor + 2) for divisor in xrange(5, int(math.sqrt(n))+1, 6))return n % 2 and n % 3 and all(n % divisor and n % (divisor + 2) for divisor in xrange(5, int(math.sqrt(n))+1, 6))Context
StackExchange Code Review Q#55691, answer score: 11
Revisions (0)
No revisions yet.