在python中检查数字是素数,为什么检查到int(sqrt(n)-1))而不是int(sqrt(n))

在python中检查数字是素数,为什么检查到int(sqrt(n)-1))而不是int(sqrt(n)),python,Python,这里是Python新手。我试图理解这个函数是如何检查素数的: from itertools import count, islice from math import sqrt def is_prime(n): if n < 2: return False return all(n%i for i in islice(count(2), int(sqrt(n)-1))) 来自itertools导入计数,islice 从数学导入sqrt def是_prime(n): 如果n

这里是Python新手。我试图理解这个函数是如何检查素数的:

from itertools import count, islice
from math import sqrt
def is_prime(n):
    if n < 2: return False
    return all(n%i for i in islice(count(2), int(sqrt(n)-1)))
来自itertools导入计数,islice
从数学导入sqrt
def是_prime(n):
如果n<2:返回False
返回全部(n%i表示岛中的i(计数(2),整数(sqrt(n)-1)))

据我所知,你可以检查小于等于和的因子,包括n的平方根,那么为什么这只是测试sqrt(n)-1?我也不清楚函数的
返回所有
部分。n%i返回一个整数,即余数。那么为什么这个表达式作为布尔值计算呢?任何关于这方面的建议都会很好。谢谢

因为
islice
的第二个参数是一个计数,而不是要停止的值

如果使用
xrange(2,int(sqrt(n))+1)

这里的加号是使范围在两端都包含,而xrange通常不包含

  • 函数是sqrt(n)的实际检查。因为islice(count(2),sqrt(n)-1表示count sqrt(n)-1从2开始的数字。当检查素数时,从2到它的平方根检查就足够了,因为即使有一个因子大于平方根,它也会有一个相应的因子小于平方根。在这里使用int(sqrt(n))意味着我们正在检查一个额外的数字——没有伤害,但没有必要。使用int(sqrt(n)-1)意味着我们只进行必要的比较

  • 如果迭代的所有元素的计算结果都为true,则all()将返回true。在python中,0的计算结果为false。这意味着,如果对于2和sqrt(n)之间的任何数字,整数除法的余数为0,则all()将返回false。这是正确的,因为如果有一个因子,这个数字就不是素数。如果对于2到sqrt(n),整数除法的余数从不为0,则该数字为prime-all()将返回true,因为迭代中没有零


  • 查看文档中的@PM2Ring,如果iterable的所有元素都为True,则返回True。但是iterable的元素是int而不是bools。在python中,0被强制转换为False,而任何其他数字在默认情况下都被强制转换为True。@Igor谢谢,得到了它在调用
    all()
    时使用这样的生成器表达式的好处是
    all()
    短路,所以
    all()
    一旦检测到生成了错误的ish值,就会停止调用生成器。换句话说,一旦找到一个因子,循环就会停止。类似的注释适用于
    any()
    -一旦生成真实的ish值,
    any()
    中的生成器表达式将立即停止。非常好,感谢您提供详细的答案。现在清楚地理解它。这是错误的-代码没有检查2到n之间的每个数字-1@Eric对这实际上是因为序列从2开始,不是1,所以必须减去1。e、 g.检查16[2,3,4,5,6,7,8,9,10,11,12,13,14,15,16]。sqrt为4。前4项是2,3,4,5,我们包括了5项,其中我们不需要sqrt(n)-1。@Eric你说得对。我已经更正了我的答案。感谢您的注意。或者在Python3中,
    range(2,int(sqrt(n))+1)
    ,尽管我更喜欢保存
    math
    模块调用并执行
    n**0.5
    而不是
    sqrt(n)