Python 列表(带质数)

Python List (with prime numbers)

我是 Python 的初学者,我需要帮助修复我创建的这段代码。 Bassicaly,我在下面有我的代码。

import math

def generate_p(p, Count, X, List):
    while Count <= X:
        isprime = True
        for x in range(2, int(math.sqrt(p)) + 1):
            if p % x == 0:
                isprime = False
        if isprime:
            Count += 1
            print p
            P.append(p)
        p += 1

if __name__ == "__main__":
    p = 2
    count = 1
    X = int(raw_input('number: '))
    List = []
    generate_p(p, count, X, List)

基本上,该功能确实有效,但是,它无法按照我希望的方式运行。首先,我将说明函数的逻辑是如何工作的,因为代码的第二部分只是变量和声明函数。
而变量 count 小于或等于 X,则 is prime 为真,只要 p(被测试的数字)可以无余数地进入每个 x(x 在 2 到 p 的平方根的范围内)。如果它是素数,则将 1 添加到计数中,打印素数,将其也添加到列表中,然后将 1 加到 p,即被测试的数字。如果它不是素数,则只需将 p 加 1。这一直持续到 Count 大于 X,然后代码停止。
正如您现在可能已经注意到的那样,有一个收集素数的列表,但是,这大部分未被使用。我想做的,但我不知道该怎么做,就是修复这部分代码,

for x in range(2, int(math.sqrt(p)) + 1):
    if p % x == 0:
        isprime = False

所以 x 在 2 和 p+1 的平方根的范围内,但是,我只希望 x 是 P 列表中该范围内的数字。任何人都可以帮我做这个,也许指出这段代码中的任何其他内容?

您可以使用 List Comprehension,像这样:

for x in [prime in P if prime<=math.sqrt(p)]:
    ...

如果您只想迭代 P 中小于或等于 p 的平方根的数字:

for x in (i for i in P if i <= math.sqrt(p)):
    if p % x == 0:
        isprime = False
        break # can stop here

请注意,将 pP 作为变量非常混乱。

虽然其他答案在逻辑上是正确的,但他们会评估 P 中的每个项目的大小。如果 P 按大小升序排序,并且 P 足够大,那么只循环遍历 P 并在循环顶部包含一个 break 子句可能更有效。

Edit 实际上,要执行此操作,您需要将此部分拆分为它自己的函数,这样您就不会终止顶层 while 循环.然后你只需 return True/False 在每个点

def is_prime(x, P):
    sqrt_p = int(math.sqrt(p)) + 1
    for x in P:
        if x > sqrt_p:
            return True
        if p % x == 0:
            return False
    return True

在其他观察方面:

  1. 尝试使用更好的名称。 X、List、P、p 等使得代码难以调试和修改。事实上,您将 List 发送到函数中但不对其执行任何操作 - 我猜 P 和 List 应该是同一件事。使用 upper_boundprime_listprime 等名称更容易 mitigated/spotted 混淆变量。还要检查 PEP8 在 Python 中的一般命名约定,这将使您的代码对其他 Python 程序员更具可读性和一致性。
  2. 与其在函数外创建一个空列表,然后将其作为参数发送,不如在函数内创建列表,追加找到的所有素数,并让函数 return列表 - 它往往会提高可读性并减少错误的范围。

我认为您正在寻找 sieve of Eratosthenes 算法。 python 实现可能如下所示:

 def erato(n):
    "Compute all prime numbers less than or equal to n"
    # utility functions in order to work only with numbers starting at 2
    def prime(i):
        return isprime[i - 2]
    def setprime(i, val):
        isprime[i - 2] = val
    # suppose all numbers may be primes until we find divisors
    isprime = [ True for i in range(2, n+1) ]
    for i in range(2, int(math.sqrt(n)) + 1):
        # do not process non prime numbers
        if prime(i):
            # if i is prime, all its multiples are not
            j = 2 * i
            while j <= n :
                setprime(j, False)
                j += i
    # return the list of prime numbers
    return [ i for i in range(2, n + 1) if prime(i) ]

看看你能不能把面条绕在这个发电机上……最快的。

def isprime(value):
    stack = [0 for i in xrange(value*2)]
    for jump in xrange(2,value,1):
        for i in xrange(jump,value*2,jump):
            stack[i] += 1
    if stack[value] > 1:
        return False
    else:
        return True

至少是我最快的方法。比检查每个数字快得多

如果您想在 p 较大时针对时间复杂度优化函数,我建议您查看 Fermats 素数检验或 Soloway strausse 素数检验。此外,公因数列表可能会派上用场!