在python中生成素数时出错

时间:2014-03-23 12:08:55

标签: python primes

我想打印从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]            

7 个答案:

答案 0 :(得分:3)

我无法弄清楚你使用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

答案 1 :(得分:2)

您应该在每个内循环开始之前将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循环更快并被视为more pythonic


有许多不同的计算素数的方法。以下是其中一些。

这是您的原始算法,有一些改进;

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

答案 2 :(得分:1)

我在您的代码中添加了两个打印语句 - 首先,在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

这告诉你为什么没有打印:在b中的a == 1循环后,c为1;在外循环的下一次迭代中的相同循环之后,c现在是3.因此,当进行该测试时,c==2永远不会为真,因此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

正如所料。

答案 3 :(得分:0)

  1. 你的c在循环内没有重置为零(第一个循环)。所以在行之后设置c = 0:为范围内(1,11):

  2. 我不知道你的k是什么。对任何事情都有用吗?

  3. 打印素数不要做[d],打印d 。您正在循环不在索引上的项目。

答案 4 :(得分:0)

试试这个:

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

请注意,代码可能更有效。

答案 5 :(得分:0)

您的代码有多个问题 - 每个素数都可以被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

答案 6 :(得分:0)

这个解决方案有点整洁:

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&gt; SQRT(a)所示。