简体   繁体   English

测试素数的更短方法

[英]Shorter way to test if prime number

To test if a number is prime, I do:为了测试一个数字是否是素数,我这样做:

def isprime(n):

    if n < 2: return False

    for i in range(2, n):
        if n % i == 0:
            return False
    else:
        return True

I wonder how to make that more efficient/shorter to write.我想知道如何使编写更有效/更短。

With generator:带发电机:

def isprime(n):
    return (all(False for i in range(2,n) if n % i == 0) and not n < 2)
    
print (isprime(0))
print (isprime(1))
print (isprime(2))
print (isprime(3))
print (isprime(9))
print (isprime(10))
print (isprime(13))

Output: Output:

False
False
True
True
False
False
True

Alongside @Théophile's suggestion, I'd add the following recommendations:除了@Théophile 的建议,我还要添加以下建议:

  1. Test whether a number is even and greater than 2 before even calling is_prime (eliminating the need for a function call).在调用 is_prime 之前测试一个数字是否为偶数且大于 2(无需调用is_prime )。

  2. Instead of range(2, n) , use range(3, n, 2) .代替range(2, n) ,使用range(3, n, 2) This will consider only odd numbers;这将只考虑奇数; the third parameters of range is the step by which you'll increment. range的第三个参数是递增的步长。

  3. Instead of looping through all the integers (or all the odd integers) less than the square root of n, create a cache of the prime numbers you've already found and loop through them.与其循环遍历小于 n 的平方根的所有整数(或所有奇数),不如创建一个已找到的素数缓存并循环遍历它们。 One of the fastest and most elegant ways to do this is using functools.lru_cache , but it will suffice simply to write provide a cache yourself.最快和最优雅的方法之一是使用functools.lru_cache ,但只需编写自己的缓存就足够了。

Here's a quick and dirty way of doing this that is longer but more efficient than your original proposal:这是一种快速而肮脏的方法,比您的原始提议更长但更有效:

from math import sqrt

# We seed the cache with the first two odd primes because (1) it's low-
# hanging fruit and (2) we avoid the need to add extra lines of code (that
# will increase execution time) for cases in which the square roots of numbers
# are less than any primes in the list
odd_primes = [3, 5]

def is_prime(n):
    
    # If n is not prime, it must have at least one factor less than its square 
    # root.
    max_prime_factor_limit = int(sqrt(n))
    
    # use a generator here to avoid evaluating all the qualifying values in 
    # odd_primes until you need them. For example, the square root of 27 is
    # 5.1962, but, since it's divisible by 3, you'll only test if 27 is prime
    # one time. Not a big deal with smaller integers, but the time to compute
    # the next prime will increase pretty fast as there are more potential
    # factors.
    
    available_primes = (p for p in odd_primes if p <= max_prime_factor_limit)
    
    for prime in available_primes:
        if n % prime == 0:
            return False
    
    return True


for i in range(7, 99, 2):
    # if no prime factors were found, add to cache
    if is_prime(i):
        odd_primes.append(i)
        
print(odd_primes)

There are additional things you can do to speed this up.您可以做一些额外的事情来加快速度。 The one that immediately springs to mind is, instead of calculating the square root of each number you're checking, use the squares of the primes to determine the upper limit of the set of primes you'll check.立即浮现在脑海的是,不是计算您要检查的每个数字的平方根,而是使用素数的平方来确定您要检查的素数集的上限。 In other words, if you know that the square of 169 is 13, so you know that any number greater than 169 and less than 289 (the square of 17) will have a prime factor <= 13. You can also use that to save time by calculating the list of prime factors and passing the list to the function you're using to determine if an integer is prime.换句话说,如果你知道 169 的平方是 13,那么你就知道任何大于 169 且小于 289(17 的平方)的数都有一个质因数 <= 13。你也可以用它来保存通过计算素数列表并将列表传递给 function 来确定 integer 是否为素数。 Note, of course, that this will only work if you're actually creating a list of primes.当然,请注意,这仅在您实际创建素数列表时才有效。

number = int(input('please enter a number:'))
if number>1:
    for numbers in range(2, number):
        if (number % numbers) ==0:
            print(f"{number} is not a prime number")
         
            break
    else:
        print(f"{number} is a prime number")  
else:
    print(f"{number} is not a prime number")

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM