素数打印机停止在 251,为啥? [复制]

Posted

技术标签:

【中文标题】素数打印机停止在 251,为啥? [复制]【英文标题】:Prime number printer stops at 251, why? [duplicate]素数打印机停止在 251,为什么? [复制] 【发布时间】:2016-10-20 10:39:47 【问题描述】:

我今天开始学习 Python,我想创建一个程序来打印从 0 到 10 000 的所有素数。我设法让我的程序打印出直到 251 的所有素数,然后停止打印出数字。为什么会这样?

代码如下:

for numberToCheck in range(2,10000):
    divider = 2
    while numberToCheck > divider:
        if numberToCheck % divider is 0:
            break
        else:
            divider += 1
    if numberToCheck is divider:
        print(numberToCheck, "is a prime number.")

【问题讨论】:

那个`(反引号)会导致语法错误。您可能需要编辑它并删除代码部分末尾的 `,除非它是用于格式化的标记。 欢迎堆栈溢出!除了您的问题之外,您可以通过不检查大于numberToCheck 一半的数字的模数来使此功能的效率提高两倍。对于任何给定的numberToCheck,大于该数字除以二的数字不可能是它的除数之一。 "is" operator behaves unexpectedly with integers, Is there a difference between == and is in Python?的可能重复 @Alex 你不能把它限制在要检查的数字的平方根吗? @Azor-Ahai 我想是的,是的!更高效:) 【参考方案1】:

问题是您使用的是is 而不是==is 运算符执行 对象标识 比较,由于 实现细节,对于低于 256 的所有数字“可能会起作用”。 251 是 256 以下的最大素数(检查here,下一个素数是 257),然后is 返回False

>>> 254 + 1 is 255
True
>>> 255 + 1 is 256
True
>>> 256 + 1 is 257
False

相等运算符是==

>>> 254 + 1 == 255
True
>>> 255 + 1 == 256
True
>>> 256 + 1 == 257
True

【讨论】:

【参考方案2】:

使用== 来检查数字是否相等:

for numberToCheck in range(2,10000):
    divider = 2
    while numberToCheck > divider:
        if numberToCheck % divider is 0:
            break
        else:
            divider += 1
    if numberToCheck == divider:
        print(numberToCheck, "is a prime number.")

Is 运算符用于检查两个对象的id,而== 运算符用于检查它们的值。

Python 为 -5256 之间的值实现了一个整数数组,当您在此范围内创建一个 int 对象时,您将获得对现有数组实现的引用。这就是为什么 id 在这个范围内的所有整数对象中是相同的,但对于这个范围之外的整数对象是不同的,如下所示:

>>> a = -6
>>> b = -6
>>> a is b      # a and b has different id
False

>>> a = -5
>>> b = -5
>>> a is b      # a and b has same id
True

>>> a = 256
>>> b = 256
>>> a is b      # a and b has same id
True

>>> a = 257
>>> b = 257
>>> a is b      # a and b has different id
False

这就是原因,您的程序打印素数直到 251 而不是 next 素数 257 和之后,但是您的程序确实运行到 numberToCheck 到达 9999

另外,您可以考虑使用更快的算法来生成素数,例如Sieve of Eratosthenes。

基本上,您应该检查numberToCheck2 和(之前找到的numberToCheck 的素数或平方根,以较小者为准)之间的所有素数 的可分性。

【讨论】:

【参考方案3】:

错误在最后一个if。改成

if numberToCheck is divider:

if numberToCheck == divider:

说明: is 测试引用是否相等,而 == 检查值的相等性(更具体地说,它在您的元素上调用 __eq__ 方法)

第一个质数打印到 251 的原因是因为 python 缓存了所有小整数。

例如:

>>> 100 == 10**2
True
>>> 100 is 10**2
True
>>> 1000 == 10**3
True
>>> 1000 is 10**3
False

(示例取自here) 您应该只使用is 来检查引用(对象不仅应该相等,而且应该是相同的实例)或与None 进行比较。

【讨论】:

【参考方案4】:

切勿将整数与is 进行比较。始终使用==

== 应该用于比较数字。

这里是固定代码:

for numberToCheck in range(2,10000):
divider = 2
while numberToCheck > divider:
    if numberToCheck % divider == 0:
        break
    else:
        divider += 1
if numberToCheck == divider:
    print(numberToCheck, "is a prime number.")

【讨论】:

【参考方案5】:

问题是你使用了isis 不检查相等性,它检查对象的身份(内存地址);对象 a 是否与对象 b 相同?

请参考以下问题:

Is there a difference between `==` and `is` in Python?

"is" operator behaves unexpectedly with integers

Why (0-6) is -6 = False?


解决你的问题:

def prime(numberToCheck):
    divider = 2
    while numberToCheck > divider:
        if numberToCheck % divider == 0:
            break
        else:
            divider += 1

        if numberToCheck == divider:
            print(numberToCheck, "is a prime number.")

这里有一点琐碎的说明,但在大型应用程序中可能很重要:我创建了一个名为 prime 的函数来最大限度地重复使用代码。现在您可以通过prime 函数来检查您喜欢的任何数字是否是素数,这比硬编码您要测试的数字要好得多!

【讨论】:

【参考方案6】:

您不得将数字与is 进行比较。始终使用== 进行相等性测试。

【讨论】:

【参考方案7】:

您使用的是 is 而不是 ==。 无论如何,代码明智的你正在浪费资源检查这样的素数。你应该只检查从 2 到 sqrt(n) 并且你应该最好保留质数并只检查它们直到你到达它们,例如你正在检查数字 41 是否是质数,检查质数 2 3 5 然后你知道它不是素数(因为素数和 sqrt 之间的所有其他数字都不是素数,所以您已经检查过它们) 随手创建一个素数列表。

试试这个代码:

import math
primes = [2]
for n in range(3,100):
    for i in primes:
        if n in primes:
            break
        if n%i == 0:
            break
        if i> math.sqrt(n):
            primes.append(n)
            break

【讨论】:

【参考方案8】:

This link会帮助你为什么不使用is

In [5]: a = 254+1

In [6]: b = 255

In [7]: a is b  # both are same objects
Out[7]: True

In [8]: id(a)
Out[8]: 37644344 # id of a

In [9]: id(b)
Out[9]: 37644344   # same id as a

对于 > 256

In [10]: a = 256+1

In [11]: b = 257

In [12]: a is b # both are different objects but values are same
Out[12]: False

In [13]: id(a)
Out[13]: 39721992 # id of a

In [14]: id(b)
Out[14]: 39722592 # new id created not same as a

is 总是与对象而不是值进行比较

为什么只有 256 个?

来自python docs

当前的实现为所有人保留一个整数对象数组 -5 到 256 之间的整数,当您在该范围内创建一个 int 时,您 实际上只是取回对现有对象的引用。

当您分配 a=255 时,您只是将 a 添加为引用现有的 255。当 a=257 将创建新的 int 类型对象时

【讨论】:

以上是关于素数打印机停止在 251,为啥? [复制]的主要内容,如果未能解决你的问题,请参考以下文章

为啥 Banana 在 JavaScript 中打印? [复制]

为啥在输出中打印“无”? [复制]

为啥这个 `else` 块可以工作,但它与 `if` 情况不在同一级别? [复制]

为啥打印功能没有在正确的时间运行? [复制]

有没有办法打印这个未显示的标签文本? [复制]

为啥数组在通过其他更改数组的方法时打印不同? [复制]