检查数字是否是Python中的素数

时间:2010-11-06 17:16:09

标签: python primes

我写了下面的代码,应该检查输入的号码是否是素数,但是有一个问题我无法通过:

def main():
n = input("Please enter a number:")
is_prime(n)

def is_prime(a):
    x = True 
    for i in (2, a):
            while x:
               if a%i == 0:
                   x = False
               else:
                   x = True


    if x:
        print "prime"
    else:
        print "not prime"

main()

如果输入的数字不是素数,则显示“非素数”,因为它应该是,但如果数字是素数,则它不显示任何内容。你能帮帮我吗?

8 个答案:

答案 0 :(得分:93)

以下是我对这个问题的看法:

from math import sqrt; from itertools import count, islice

def isPrime(n):
    return n > 1 and all(n%i for i in islice(count(2), int(sqrt(n)-1)))

这是一个非常简单和简洁的算法,因此它并不意味着接近最快或最优的素数检查算法。它的时间复杂度为O(sqrt(n))前往here了解更多关于正确完成的素性测试及其历史


说明

我会给你一些关于那些将检查素数的几乎深奥的单行代码的内容:

  • 首先,使用range()确实是一个坏主意,因为它会创建一个使用大量内存的数字列表。使用xrange()会更好,因为它会创建一个生成器,它只需要记住您提供的初始参数,并在运行中生成每个数字。如果你正在使用 默认情况下,Python 3或更高版本range()已转换为生成器。顺便说一句,这根本不是最好的解决方案:尝试为xrange(n)调用n,使n > 231-1(这是C long的最大值)提出OverflowError。因此创建范围生成器的最佳方法是使用itertools

    xrange(2147483647+1) # OverflowError
    
    from itertools import count, islice
    
    count(1)                        # Count from 1 to infinity with step=+1
    islice(count(1), 2147483648)    # Count from 1 to 2^31 with step=+1
    islice(count(1, 3), 2147483648) # Count from 1 to 3*2^31 with step=+3
    
  • 如果您想检查n是否为素数,则实际上不需要一直到n 。您可以大大减少测试,只检查从2到√(n)n的平方根)。这是一个例子:

    让我们找到n = 100的所有除数,并将它们列在表中:

     2  x  50 = 100
     4  x  25 = 100
     5  x  20 = 100
    10  x  10 = 100 <-- sqrt(100)
    20  x  5  = 100     
    25  x  4  = 100
    50  x  2  = 100
    

    您很容易注意到,{strong>在n的平方根之后,我们找到的所有除数实际上已经找到了。例如20已经找到了100/5。数字的平方根是我们发现的除数开始重复的确切中点。因此,要检查数字是否为素数,您只需要检查2到sqrt(n)

  • 为什么选择sqrt(n)-1,而不只是sqrt(n)?那是因为提供给itertools.islice对象的第二个参数是要执行的迭代次数。 {strong> islice(count(a), b)b次迭代后停止。这就是为什么:

    for number in islice(count(10), 2):
        print number,
    
    # Will print: 10 11
    
    for number in islice(count(1, 3), 10):
        print number,
    
    # Will print: 1 4 7 10 13 16 19 22 25 28
    
  • 函数all(...)与以下内容相同:

    def all(iterable):
        for element in iterable:
            if not element:
                return False
        return True
    

    字面检查iterable中的所有数字,当数字评估为False 时返回False(这意味着只有数字为零) )。那我们为什么要用呢?首先,我们不需要使用额外的索引变量(就像我们使用循环一样),除此之外:只是为了简洁,没有真正需要它,但它看起来不那么笨重一行代码而不是几行嵌套行。

扩展版

我包含isPrime()函数的“解压缩”版本,以便更容易理解和阅读:

from math import sqrt
from itertools import count, islice

def isPrime(n):
    if n < 2:
        return False

    for number in islice(count(2), int(sqrt(n) - 1)):
        if n % number == 0:
            return False

    return True

答案 1 :(得分:69)

有许多有效的方法可以测试primality(这不是其中之一),但你编写的循环可以用Python简洁地重写:

def is_prime(a):
    return all(a % i for i in xrange(2, a))

也就是说,如果a和2之间的所有数字(不包括在内)在分成a时给出非零余数,则a为素数。

答案 2 :(得分:29)

如果只有少量查询,这是查看数字是否为素数的最有效方法。如果你问了很多数字,如果他们是最好的尝试Sieve of Eratosthenes

import math

def is_prime(n):
    if n == 2:
        return True
    if n % 2 == 0 or n <= 1:
        return False

    sqr = int(math.sqrt(n)) + 1

    for divisor in range(3, sqr, 2):
        if n % divisor == 0:
            return False
    return True

答案 3 :(得分:8)

如果a是素数,则代码中的while x:将永久运行,因为x将保持True

那么为什么那里有while

我认为你想在找到一个因子时结束for循环,但不知道怎么做,所以你添加了它,因为它有一个条件。所以这就是你如何做到的:

def is_prime(a):
    x = True 
    for i in range(2, a):
       if a%i == 0:
           x = False
           break # ends the for loop
       # no else block because it does nothing ...


    if x:
        print "prime"
    else:
        print "not prime"

答案 4 :(得分:0)

def prime(x):
    # check that number is greater that 1
    if x > 1:
        for i in range(2, x + 1):
            # check that only x and 1 can evenly divide x
            if x % i == 0 and i != x and i != 1:
                return False
        else:
            return True
    else:
        return False # if number is negative

答案 5 :(得分:0)

def is_prime(x):
    n = 2
    if x < n:
        return False
    else:    
        while n < x:
           print n
            if x % n == 0:
                return False
                break
            n = n + 1
        else:
            return True

答案 6 :(得分:-3)

a = input('inter a number: ')
s = 0
if a == 1:  
    print a, 'is a prime'

else : 

    for i in range (2, a ):

        if a%i == 0:
            print a,' is not a prime number'
            s = 'true'
            break

    if s == 0 : print a,' is a prime number'

它与我合作很好:D

答案 7 :(得分:-4)

def isPrime(x):
    if x<2:
        return False
    for i in range(2,x):
        if not x%i:
           return False
    return True  
  

print isPrime(2)
  真的   print isPrime(3)
  真的   print isPrime(9)
  假