【问题标题】:Improve code to find prime numbers改进代码以查找素数
【发布时间】:2018-06-08 02:16:01
【问题描述】:

我大约3天前写了这个python代码,我卡在这里,我认为它可以更好,但我不知道如何改进它。你们能帮帮我吗?

# Function
def is_prime(n):
    if n == 2 or n == 3:
        return True

    for d in range(3, int(n**0.5), 2):
        if n % d == 0:
            return False

    return True

【问题讨论】:

标签: python performance primes


【解决方案1】:

找到相对较小素数的一个很好的确定方法是使用sieve

这项技术背后的数学原理如下:要检查一个数是否为素数,只需检查它是否不能被其他素数整除。

import math

def is_prime(n):
    # Prepare our Sieve, for readability we make index match the number by adding 0 and 1
    primes = [False] * 2 + [True] * (n - 1)

    # Remove non-primes
    for x in range(2, int(math.sqrt(n) + 1)):
        if primes[x]:
            primes[2*x::x] = [False] * (n // x - 1)

    return primes[n]

    # Or use the following to return all primes:
    # return {x for x, is_prime in enumerate(primes) if is_prime}

print(is_prime(13)) # True

为了可重用性,您可以修改上面的代码以返回所有素数的set,直到n

【讨论】:

  • 我试过这个,但是要确定一个大数是否是素数,这种方法实际上会减慢代码,因为它甚至必须找到另一个素数,所以:如果 n 是 500,它会检查每个小于 500 的素数,并进行比较。抱歉,如果我没有提到我正在寻找大数字
  • @Locked 你似乎误解了素数。检查一个数是否为素数的唯一确定性方法是检查它是否可被其他素数整除。此解决方案与 sympy.isprime 所做的相同,特别是:它更快
  • 我明白了,但至少在我的设备中,使用 sympy 甚至使用我第一次使用的代码会更快。要检查 1 到 1000000 之间的每个数字,结果如下: 第一个代码:大约 3 秒 Sympy:大约 2 秒 使用此方法:超过 5 分钟
  • @Locked 如上所述,如果您需要测试多个数字,只需返回所有素数的集合,那么一次调用就足够了。 sympy 可能会缓存它的筛子
  • @Locked 查看我在函数底部添加的注释返回语句
【解决方案2】:

试试下面的代码,它的速度和 Olivier Melançon 的解决方案一样:

from math import sqrt; from itertools import count, islice

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

print(is_prime(5))

输出:

True

【讨论】:

  • 我很好奇,在使用 sympy 和我写的基于切片的筛子作为答案之间会更快吗?我没有 sympy,你能对其进行基准测试吗?
  • @OlivierMelançon 哦,是的,你是对的,你的速度要快得多
  • 我真的很惊讶,但很高兴读到这篇文章,我从未对其进行基准测试,请问是多少?
  • @OlivierMelançon 写了这么多0.8281598091125488
猜你喜欢
  • 2017-05-23
  • 2016-02-21
  • 1970-01-01
  • 2012-03-31
  • 1970-01-01
  • 2019-03-29
  • 1970-01-01
  • 2015-05-12
  • 2023-04-06
相关资源
最近更新 更多