检查数字 N 是否为素数的一个非常简单明了的蛮力解决方案:只需检查从 2 到 N 的平方根之间是否存在 N 的除数(如果有兴趣,请参阅为什么 here)。
以下代码同时兼容 Python 2 和 Python 3:
from math import sqrt
from itertools import count, islice
def is_prime(n):
return n > 1 and all(n % i for i in islice(count(2), int(sqrt(n) - 1)))
这是一个更简单的仅 Python 3 实现:
def is_prime(n):
return n > 1 and all(n % i for i in range(2, int(n ** 0.5) + 1))
为了清楚起见,这里是上述的扩展版本:
from math import sqrt
from itertools import count, islice
def is_prime(n):
if n < 2:
return False
for divisor in islice(count(2), int(sqrt(n) - 1)):
if n % divisor == 0:
return False
return True
def is_prime(n):
if n < 2:
return False
for divisor in range(2, int(n ** 0.5) + 1):
if n % divisor == 0:
return False
return True
这并不意味着任何接近最快或最优的素数检查算法,它只是实现了简单和简洁的目标,这也减少了实现错误。它的时间复杂度为O(sqrt(n))。
如果您正在寻找更快的算法来检查数字是否为素数,您可能会对以下内容感兴趣:
实施说明
您可能已经注意到,在与 Python 2 兼容的实现中,我将itertools.count() 与itertools.islice() 结合使用,而不是简单的range() 或xrange()(旧的Python 2 生成器范围,在 Python 3 中是默认值)。这是因为在 CPython 2 xrange(N) 中,对于某些 N 使得 N > 263 ‒ 1 (或 N > 231 ‒ 1 取决于实现)引发一个 @ 987654341@。这是一个不幸的 CPython 实现细节。
我们可以使用itertools 来解决这个问题。由于我们使用itertools.count(2) 从2 计数到无穷大,所以在sqrt(n) - 1 步骤之后我们将达到sqrt(n),我们可以使用itertools.islice() 限制生成器。