在python

时间:2017-03-16 17:18:47

标签: python primes

我试图创建一个菜单驱动的程序,它将计算并显示2和用户输入限制之间的所有素数。用户可以选择的第一个选项是"使用Sieve of Eratosthenes算法"创建从2到n的素数列表。第二个选项是"显示素数",第三个选项是退出。我的代码目前看起来像:

def main():
    choice = displayMenu()
    while choice!= '3':
        if choice == '1':
            sieve()
        elif choice == '2':
            prime
        choice = displayMenu()

    print("Thanks for playing!")
def displayMenu():
    myChoice = '0'
    while myChoice != '1' and myChoice != '2' and myChoice != '3':
        print("""Please choose
                      1. Create a list of primes from 2 to n using
                      the Sieve of Eratosthenes algorithm
                      2. Display the prime numbers
                      3. Quit
                      """)
        myChoice = input("Enter option--->")

        if myChoice != '1' and myChoice != '2' and myChoice != '3':
            print("Invalid option. Please select again.")

    return myChoice

def sieve():
    liste = [ ]
    n = int(input("What number should I go up to?"))
    choice = input("--->")
    for primeCandidate in range (2,n):
        isPrime = True
        for divisor in range (2, primeCandidate):
            if primeCandidate % divisor == 0:
                isPrime = False
                break
            if isPrime:
                liste.append(primeCandidate)
                print(liste)
main()

我发现的是,当我从2到13打印质数时,例如它将其打印为

[3]
[3, 5]
[3, 5, 5]
[3, 5, 5, 5]
[3, 5, 5, 5, 7]
[3, 5, 5, 5, 7, 7]
[3, 5, 5, 5, 7, 7, 7]
[3, 5, 5, 5, 7, 7, 7, 7]
[3, 5, 5, 5, 7, 7, 7, 7, 7]
[3, 5, 5, 5, 7, 7, 7, 7, 7, 9]
[3, 5, 5, 5, 7, 7, 7, 7, 7, 9, 11]
[3, 5, 5, 5, 7, 7, 7, 7, 7, 9, 11, 11]
[3, 5, 5, 5, 7, 7, 7, 7, 7, 9, 11, 11, 11]
[3, 5, 5, 5, 7, 7, 7, 7, 7, 9, 11, 11, 11, 11]
[3, 5, 5, 5, 7, 7, 7, 7, 7, 9, 11, 11, 11, 11, 11]
[3, 5, 5, 5, 7, 7, 7, 7, 7, 9, 11, 11, 11, 11, 11, 11]
[3, 5, 5, 5, 7, 7, 7, 7, 7, 9, 11, 11, 11, 11, 11, 11, 11]
[3, 5, 5, 5, 7, 7, 7, 7, 7, 9, 11, 11, 11, 11, 11, 11, 11, 11]
[3, 5, 5, 5, 7, 7, 7, 7, 7, 9, 11, 11, 11, 11, 11, 11, 11, 11, 11]

有没有办法纠正这个并且只打印一次素数?

2 个答案:

答案 0 :(得分:3)

sieve函数中的缩进是错误的。这样,您可以在循环的每次迭代中将主要候选项添加到列表中,并立即打印列表。相反,您应该在测试 all 除数后,即在内循环之后添加主要候选者,并且只有在找到所有素数时才打印数字,即在外部循环之后。

试试这个(标记更改的行):

def sieve():
    liste = [ ]
    n = int(input("What number should I go up to?"))
    choice = input("--->")
    for primeCandidate in range (2,n):
        isPrime = True
        for divisor in range (2, primeCandidate):
            if primeCandidate % divisor == 0:
                isPrime = False
                break
        if isPrime: # only check isPrime after the loop completed
            liste.append(primeCandidate)
    print(liste)  # only print the list once

此外,如注释中所述,您可能希望将实际算法与用户交互部分分开,并且可以使用更紧凑的all函数和生成器表达式而不是内部循环。而且您不必检查所有数字primeCandidate;相反,只需检查迄今已知的素数。:

def sieve(n): # pass n as parameter
    liste = [ ]
    for primeCandidate in range (2,n):
        # use all with generator, and only check known primes
        isPrime = all(primeCandidate % divisor != 0 for divisor in liste)
        if isPrime:
            liste.append(primeCandidate)
    return liste  # return, don't print

最后,请注意,严格来说,这是而不是 a Sieve of Erastothenes!一个真正的筛子将会越过"越过"标识为素数的倍数,而使用试验除法,您的代码几乎完全相反。两者都有效,但除法通常比乘法慢。

有关不同Prime数字算法的详细讨论,请参阅this related question

答案 1 :(得分:0)

你有没有看过set?然后为要添加到集合中的每个新整数执行set.add?

例如:

In [24]: a=[1]

In [25]: set(a)
Out[25]: {1}

In [26]: b=[1,1]

In [27]: set(b)
Out[27]: {1}

In [28]: c=set(b)

In [29]: c.add(1)

In [30]: c
Out[30]: {1}

In [31]: c.add(2)

In [32]: c
Out[32]: {1, 2}