簡體   English   中英

在Python中生成素數的錯誤

[英]error in generating prime numbers in python

我想打印所有從1到10的質數,但是運行程序時什么也沒打印

c=0
nums = []                   
k=0
for a in range(1,11):          
    for b in range(1,11):
        if a%b==0:          
            c = c+1        
    if c==2:                  
        nums.append(a)      
        k = k+1 
for d in nums:              
    print nums[d]            

我不知道你為什么使用k

並且您的c應該在“ a”循環中和從“ b”循環中重置

像這樣的代碼:

nums = []

for a in range(1, 11):
    c = 0
    for b in range(1, 11):
        if a % b == 0:
            c = c + 1
    if c == 2:
        nums.append(a)
print nums

在每個內部循環開始之前,應將c重置為零:

nums = []                   
for a in range(1,11):
    c = 0         
    for b in range(1,11):
        if a%b==0:          
            c = c+1        
    if c==2:                  
        nums.append(a)      
for d in nums:              
    print d

另外,您應該使用print d ,因為for循環已經以nums給出了每個元素。

與使用for -loop相比,使用列表理解通常更快,並且被認為更Python化


有許多不同的計算素數的方法。 這里是其中的一些。

這是您的原始算法,並做了一些改進;

def prime_list(num):
    """Returns a list of all prime numbers up to and including num.

    :num: highest number to test
    :returns: a list of primes up to num
    """
    if num < 3:
        raise ValueError('this function only accepts arguments > 2')
    candidates = range(3, num+1, 2)
    L = [c for c in candidates if all(c % p != 0 for p in range(3, c, 2))]
    return [2] + L
  • 對於素數> 2,它們必須是奇數。 因此, candidates應只包含奇數。
  • 為了使奇數c為質數,必須確保c所有以前的奇數( p )取模必須為非零。
  • 最后,2也是素數。

進一步的改進是將p限制為sqrt(c)

import math

def prime_list2(num):
    if num < 3:
        raise ValueError('this function only accepts arguments > 2')
    candidates = range(3, num+1, 2)
    L = [c for c in candidates if all(c % p != 0 for p in
         range(3, int(math.sqrt(c))+1, 2))]
    return [2] + L

另一個實現:

def prime_list3(num):
    num += 1
    candidates = range(3, num, 2)
    results = [2]
    while len(candidates):
        t = candidates[0]
        results.append(t)
        candidates = [i for i in candidates if not i in range(t, num, t)]
    return results

這從包含所有奇數的候選列表開始。 然后,通過刪除前一個列表的第一個數字及其所有倍數來計算新的候選列表。

讓我們看一下算法的速度。

對於較小的數字,原始的prime_list最快。

In [8]: %timeit prime_list(10)
100000 loops, best of 3: 8.68 µs per loop

In [9]: %timeit prime_list2(10)
100000 loops, best of 3: 10.9 µs per loop

In [10]: %timeit prime_list3(10)
100000 loops, best of 3: 8.96 µs per loop

對於更大的數字, prime_list2會成為贏家:

In [5]: %timeit prime_list(1000)
100 loops, best of 3: 8.28 ms per loop

In [6]: %timeit prime_list2(1000)
100 loops, best of 3: 2.46 ms per loop

In [7]: %timeit prime_list3(1000)
10 loops, best of 3: 23.5 ms per loop

In [11]: %timeit prime_list(10000)
1 loops, best of 3: 646 ms per loop

In [12]: %timeit prime_list2(10000)
10 loops, best of 3: 25.4 ms per loop

In [13]: %timeit prime_list3(10000)
1 loops, best of 3: 2.13 s per loop

我在您的代碼中添加了兩個打印語句-首先,在if a%b==0: ,我添加了print a,b 然后在循環之后打印c的最終值。 我得到以下輸出:

1 1
1
2 1
2 2
3
3 1
3 3
5
4 1
4 2
4 4
8
5 1
5 5
10
6 1
6 2
6 3
6 6
14
7 1
7 7
16
8 1
8 2
8 4
8 8
20
9 1
9 3
9 9
23
10 1
10 2
10 5
10 10
27

這告訴您為什么什么都沒打印出來: a == 1b循環之后,c為1; 在外部循環的下一次迭代中的相同循環之后,c現在為3。因此,進行該測試時c==2永遠不會為True,因此nums保持為空。

這也為您提供了一個修復程序所需的重要提示。 c不斷增加,但是它應該在外循環的每次迭代中重新開始計數-因此,將c=0移到外for循環內。 您還需要將最終的打印循環更改為print d而不是print nums[d] ,否則您將得到另一個錯誤。 經過這些更改,您的代碼如下所示:

nums = []                   
k=0
for a in range(1,11):          
    c=0
    for b in range(1,11):
        if a%b==0:
            c = c+1        
    if c == 2:                  
        nums.append(a)      
        k = k+1 
for d in nums:              
    print d

它打印

2
3
5
7

如預期的那樣。

  1. 您的c不會在循環(第一個循環)內重置為零。 因此,在第a行后將c = 0設置為range(1,11):

  2. 我不知道你的k是干什么的。 它對任何事情有用嗎?

  3. 打印素數不做nums [d], 打印d 您正在循環而不是在索引上的項目。

嘗試這個:

nums = []                   
k=0
for a in range(2,11):          
    c=0
    for b in range(1,11):
        if a%b==0:          
            c = c+1      
    if c==2: 
        nums.append(a)      
        k = k+1
for d in nums:              
    print d

你會得到

2
3
5
7

注意,代碼可能更有效。

您的代碼有多個問題-每個質數都可以被1整除,因此您的檢查將失敗,您正在打印nums[d] ,這是錯誤的, k沒有執行任何操作,變量名稱過於混淆,for循環中有不必要的運行-您不需要迭代范圍內b的所有值,迭代現有的素數就足夠了,依此類推。

這是我的寫法

primes = [2]
upper_limit = 1000 #find all primes < 1000

for candidate in range(2, upper_limit):
    can_be_prime = True
    for prime in primes:
        if candidate % prime == 0:
            can_be_prime = False
            break
    if can_be_prime:
        primes.append(candidate)

print primes

這個解決方案有點整潔:

nums = []
for a in range(2, 101):
    for b in range(2, a):
        if a % b == 0:
            break
    else:
        nums.append(a)
print nums

輸出:

[2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97]

不過,嘗試b> sqrt(a)毫無意義。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM