python素数之和

时间:2013-06-20 19:57:40

标签: python sum primes

我想制作一个python程序,它会生成一个数字的素数之和,但程序没有给出正确的结果,请告诉我原因。

b=1
#generates a list of numbers.
while b<100:
    b=b+1
    x = 0.0
    a = 0
    d = 0
    #generates a list of numbers less than b. 
    while x<b:
        x=x+1
        #this will check for divisors. 
        if (b/x)-int(b/x) == 0.0:
            a=a+1
        if a==2:
            #if it finds a prime it will add it.
            d=d+b
print d 

我让它成功生成素数列表,但是我无法添加素数。

这是我用来生成素数列表的代码。

b=1
while b<1000:
    b=b+1
    n = b
    x = 0.0
    a = 0
    while x<n:
        x=x+1
        if (n/x)-int(n/x) == 0.0:
            a=a+1
    if a==2:
        print b

6 个答案:

答案 0 :(得分:4)

在外循环的每次迭代期间,您的d变量正在重置。将初始化移出该循环。

此外,a == 2检查应该只在外循环的每次迭代中发生一次。将其移出内循环。

b=1
d = 0
#generates a list of numbers.
while b<100:
    b=b+1
    x = 0.0
    a = 0
    #generates a list of numbers less than b. 
    while x<b:
        x=x+1
        #this will check for divisors. 
        if (b/x)-int(b/x) == 0.0:
            a=a+1
    if a==2:
        #if it finds a prime it will add it.
        d=d+b
print d 

结果:

1060

虽然我们正在努力,但让我们尝试清理代码,以便更容易理解。您可以将内部循环移动到其自己的功能中,以便读者可以更清楚地了解其目的:

def is_prime(b):
    x = 0.0
    a = 0
    while x<b:
        x=x+1
        #this will check for divisors. 
        if (b/x)-int(b/x) == 0.0:
            a=a+1
    if a==2:
        return True
    else:
        return False

b=1
d=0
#generates a list of numbers.
while b<100:
    b=b+1
    if is_prime(b):
        d=d+b
print d

使用描述它们代表的变量名称也很有用:

def is_prime(number):
    candidate_factor = 0
    amount_of_factors = 0
    while candidate_factor<number:
        #A += B is equivalent to A = A + B
        candidate_factor += 1
        #A little easier way of testing whether one number divides another evenly
        if number % candidate_factor == 0:
            amount_of_factors += 1
    if amount_of_factors == 2:
        return True
    else:
        return False

number=1
prime_total=0
#generates a list of numbers.
while number<100:
    number += 1
    if is_prime(number):
        prime_total += number
print prime_total

for循环比增加计数器的while循环更具风格性:

def is_prime(number):
    amount_of_factors = 0
    for candidate_factor in range(1, number+1):
        if number % candidate_factor == 0:
            amount_of_factors += 1
    if amount_of_factors == 2:
        return True
    else:
        return False

prime_total=0
#generates a list of numbers.
for number in range(2, 101):
    if is_prime(number):
        prime_total += number
print prime_total

如果你感觉大胆,你可以使用列表推导来减少你使用的循环次数:

def is_prime(number):
    factors = [candidate_factor for candidate_factor in range(1, number+1) if number % candidate_factor == 0]
    return len(factors) == 2

#generates a list of numbers.
primes = [number for number in range(2, 101) if is_prime(number)]
prime_total = sum(primes)
print prime_total

答案 1 :(得分:3)

凯文正确地回答了你问的问题。请允许我回答你没有提出的问题,但应该有:计算小于 n 的素数之和的最佳方法是什么。答案是使用筛子:

def sumPrimes(n):
    sum = 0
    sieve = [True] * (n+1)
    for p in range(2, n):
        if sieve[p]:
            sum += p
            for i in range(p*p, n, p):
                sieve[i] = False
    return sum

这段代码实现了Eratosthenes的Sieve,总结了素数。它的工作原理是重复选择最小的未交叉数字(上面代码中的 p ,在sieve[p]True时选择),然后将其所有的倍数( i 在上面的代码中,从 p 增加以计算 p 的倍数)从其正方形开始(因为所有较小的复合已经被划掉了) )。该函数的示例使用是print sumPrimes(100),它打印1060,这是正确的答案。

请注意,罗兰的回答没有实现Eratosthenes的筛选,尽管他声称它确实如此;使用模数函数是罗兰的答案使用试验分裂的赠品,不是 Eratosthenes的筛子。

如果您对使用素数进行编程感兴趣,我会在我的博客上谦虚地推荐这个essay

答案 2 :(得分:1)

如果您为了学习python而这样做,那么有更简洁(>&gt;&gt;不易出错)的方法。从你的问题我假设你试图总结下面的所有素数,包括100

sum=0
limit=100
for n in range(2,limit+1):
  if all(n % i for i in range(2, n)):
    sum += n
print sum

打印1060

答案 3 :(得分:1)

列表推导是Python中的一个强大工具。将它们视为类固醇的循环。 :-)你可以用它们来实现试验分割,这是一种寻找素数的简单方法。

它的工作原理如下:

In [4]: sum(prime_list(100))
Out[4]: 1061

prime_list功能:

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

    :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) # (a)
    L = [c for c in candidates if all(c % p != 0 for p in range(3, c, 2))] #(b)
    return [1, 2] + L

现在解释一下。除2外,所有素数都是奇数。所以从3到num的所有奇数(在这种情况下为100)都是素数的候选者。让我们生成一个列表,如(a)所示:

In [5]: num = 100

In [6]: range(3, num+1, 2)
Out[6]: [3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29, 31, 33, 35, 37, 39, 41, 43, 45, 47, 49, 51, 53, 55, 57, 59, 61, 63, 65, 67, 69, 71, 73, 75, 77, 79, 81, 83, 85, 87, 89, 91, 93, 95, 97, 99]

对于奇数c为素数,必须确保c模数所有先前的奇数p必须为非零。假设c是25。

In [7]: c = 25

然后p在:

In [8]: range(3, c, 2)
Out[8]: [3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23]

现在检查c modulo p

In [9]: [c % p != 0 for p in range(3, c, 2)]
Out[9]: [True, False, True, True, True, True, True, True, True, True, True]

我们知道25%5 == 0,所以列表中的第二项是False。但是,要使数字成为素数,列表中的所有项都必须为真:

In [10]: all(c % p != 0 for p in range(3, c, 2))
Out[10]: False

所以25不是素数。

让我们再试一次c是41:

In [11]: c = 41

In [12]: range(3, c, 2)
Out[12]: [3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29, 31, 33, 35, 37, 39]

In [13]: [c % p != 0 for p in range(3, c, 2)]
Out[13]: [True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True]

In [14]: all(c % p != 0 for p in range(3, c, 2))
Out[14]: True

事实上,41岁是一个黄金时期。

所以prime_list返回一个素数列表:

In [15]: prime_list(100)
Out[15]: [1, 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]

总结一下,我们只需使用sum()函数:

In [16]: sum(prime_list(100))
Out[16]: 1061

编辑:根据评论,我尝试了WillNess建议的改进和使用套装的真实筛选:

def prime_list(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 [1, 2] + L

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 [1, 2] + L

def prime_list3(num):
    candidates = set(range(3, num+1, 2))
    results = [1, 2]
    while candidates:
        t = list(candidates)[0]
        results.append(t)
        candidates -= set(range(t, num+1, t))
    return results

num=100的一些时间安排:

In [8]: %timeit prime_list(100)
1000 loops, best of 3: 180 us per loop

In [9]: %timeit prime_list2(100)
1000 loops, best of 3: 192 us per loop

In [10]: %timeit prime_list3(100)
10000 loops, best of 3: 83.9 us per loop

num=1000

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

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

In [13]: %timeit prime_list3(1000)
1000 loops, best of 3: 1.26 ms per loop

num = 5000

In [14]: %timeit prime_list(5000)
1 loops, best of 3: 166 ms per loop

In [15]: %timeit prime_list2(5000)
100 loops, best of 3: 11.1 ms per loop

In [16]: %timeit prime_list3(5000)
100 loops, best of 3: 15.3 ms per loop

最后num=50000

In [18]: %timeit prime_list3(50000)
1 loops, best of 3: 1.49 s per loop

In [19]: %timeit prime_list2(50000)
1 loops, best of 3: 170 ms per loop

答案 4 :(得分:0)

使用您用于生成列表的代码对列表求和:

d = sum(d)
print d

答案 5 :(得分:0)

def sum_of_prime(num):
        if num < 2:
            return 'Please enter values greater than 2'
        if num == 2:
                return 2
        sum = 0
        for j in range(2,num):
                for i in range(2,j):
                        if (j % i) == 0:
                                break
                else:
                        print j
                        sum = sum + j
        return sum
num = int(raw_input())
result = sum_of_prime(num)
print result