I started learning Python today, and I came up with the idea of creating a program that prints all the prime numbers from 0 to 10 000. I managed to make my program print out all primes until 251, at which point it stops printing out numbers. Why does it do this?
Here is the code:
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.")
答案 0 :(得分:75)
The problem is that you are using is
instead of ==
. The is
operator performs object identity comparison, which "happens to work" for all numbers below 256
due to implementation details. 251
is the biggest prime below 256 (check here, next prime is 257) and after that the is
returns False
:
>>> 254 + 1 is 255
True
>>> 255 + 1 is 256
True
>>> 256 + 1 is 257
False
The equality operator is ==
:
>>> 254 + 1 == 255
True
>>> 255 + 1 == 256
True
>>> 256 + 1 == 257
True
答案 1 :(得分:12)
Use ==
to check equality of numbers:
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
operator is used to check the id
of two objects while ==
operator check their values.
Python implements an Array of integers for values between -5
to 256
, and when you create an int object in this range, you get a reference to the existing array implementation. That's why id
of all integers objects in this range is same but it is different for integers objects outside this range, as seen below:
>>> 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
And this is the reason, your program prints primes till 251
but not the next prime 257
and afterwards, however your program does run till numberToCheck
reaches 9999
.
Also, you might consider a faster algorithm to generate primes, such as Sieve of Eratosthenes.
Basically, you should check divisibility of numberToCheck
with all primes between 2
and ( previously found prime or square root of numberToCheck
, whichever is less ).
答案 2 :(得分:3)
The error is in the last if
. Change it from
if numberToCheck is divider:
to
if numberToCheck == divider:
Explanation:
is
tests if refences are equals while ==
check the equality of values (more specifically it calls __eq__
method on your elements)
The reasons why you have the first primes to print up to 251 is because python cache all small integers.
For example:
>>> 100 == 10**2
True
>>> 100 is 10**2
True
>>> 1000 == 10**3
True
>>> 1000 is 10**3
False
(Example taken from here)
You should use is
only to check references (objects that should not only be equals but the same instance) or to compare to None
.
答案 3 :(得分:3)
Never compare integers with is
. Always use ==
.
==
should be used to compare numbers.
Here is the fixed code:
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.")
答案 4 :(得分:3)
The problem is you used is
. is
doesn't check for equality, it checks for an object's identity (memory address); is object a the same as object b?
Refer to these questions:
Is there a difference between `==` and `is` in Python?
"is" operator behaves unexpectedly with integers
To solve your problem:
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.")
A little trivial note here, but might be crucial in larger applications: I created a function called prime
to maximize code re-use. Now you can pass the prime
function whatever number you like to check if it's prime or not, way better than hard coding the number that you want to test!
答案 5 :(得分:2)
You must not compare numbers with is
. Use always ==
for equality testing.
答案 6 :(得分:2)
you are using is instead of ==. Anyhow, code wise youre wasting resources checking for primes like this. you should only check from 2 to sqrt(n) and you should preferably keep the prime numbers and check only them until you reach them, for instance youre checking if the number 41 is a prime, check prime numbers 2 3 5 and then you know it isnt a prime (because all the other numbers between the prime and the sqrt are not prime so you already checked them) create a list of primes as you go.
try this code:
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
答案 7 :(得分:2)
This link will help you why not to use 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
for > 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
always compares with objects not values
why only upto 256?
from python docs
The current implementation keeps an array of integer objects for all integers between -5 and 256, when you create an int in that range you actually just get back a reference to the existing object.
when you assign a=255
just you are adding a
as referring excisting 255. when a=257
new int type object will be created