0

我对 Python 还是很陌生,很难在我的列表中计算我的相等数量。我创建了一个数字列表(list oneven),根据哥德巴赫的说法,每个数字都等于三个素数。我现在有一个所有素数组合的列表,现在我想计算列表中每个数字的组合数量,并将其打印出来。我尝试使用“导入集合”,但由于我的代码不可散列而无法使用。然后我厌倦了将一个数字添加到一个空列表中,该数字上升到相等的总和,但我收到错误消息:

IndexError:列表分配索引超出范围

这是我正在苦苦挣扎的代码:

lijst2 = []
lijst = []
for i in oneven:
    for a in priemgetallen:
        for b in priemgetallen:
            if a >= b:
                c = i - a - b
                if c in priemgetallen and b >= c:
                    lijst.append([c,b,a])
for item in lijst:
    if sum(item) in lijst2:
        lijst2[sum(item)] = lijst2.get(sum(item))+1
    else:
        lijst2[sum(item)] = 1

for k,v in lijst2.items():
    print(str(k)+':'+str(v))

lijst2 = set(lijst)
print(lijst2)

如果您对我正在尝试做的事情感兴趣,我正在尝试为哥德巴赫理论编写一个计数器,所以这是我的整个代码:

oneven = []
for i in range(7,102,2):
    oneven.append(i)

priemgetallen = [2]
counter = 3
while priemgetallen[-1] < oneven[-1]:
    priemgetallendelers = []
    for i in range (1,counter+1):
        if counter % i == 0:
            priemgetallendelers.append(i)
    if len(priemgetallendelers) == 2:
        priemgetallen.append(counter)
        counter += 1
    else:
        counter +=1

lijst2 = []
lijst = []
for i in oneven:
    for a in priemgetallen:
        for b in priemgetallen:
            if a >= b:
                c = i - a - b
                if c in priemgetallen and b >= c:
                    lijst.append([c,b,a])
for item in lijst:
    if sum(item) in lijst2:
        lijst2[sum(item)] = lijst2.get(sum(item))+1
    else:
        lijst2[sum(item)] = 1

for k,v in lijst2.items():
    print(str(k)+':'+str(v))

lijst2 = set(lijst)
print(lijst2)

最后它应该看起来像这样:

 7 =  2 +  2 +  3

 9 =  2 +  2 +  5
   =  3 +  3 +  3

11 =  2 +  2 +  7
   =  3 +  3 +  5

13 =  3 +  3 +  7
   =  3 +  5 +  5

Options to write: 7, 9, 11, ...:
1, 2, 2, 2, 3, 4, 3, 5, 5, 5, 7, 7, 6, 9, 8,
4

1 回答 1

0

有几个地方你的代码效率很低。首先,如果你知道你需要的素数的上限,那么埃拉托色尼筛法是一种更有效的生成素数的方法:

def primes_sieve(limit):
    if limit < 2:
        return []
    res = [2]
    odd_cnt = ((limit + 1) / 2)
    odd_sieve = [True] * odd_cnt
    odd_sieve[0] = False  # 1 is not a prime
    for (i, isprime) in enumerate(odd_sieve):
        if isprime:
            prime = 2 * i + 1
            res.append(prime)
            for n in xrange(i * (prime + 1), odd_cnt, prime):  # Mark factors non-prime, we can safely start at prime^2
                odd_sieve[n] = False
    return res

然后您的循环带有内部检查if a >= b:并且if c in priemgetallen and b >= c:效率非常低。使用 3 个嵌套循环遍历素数、获取总和并将其添加到相应的“bin”中效率更高。此外,通过记住“外部”迭代中的当前索引并从它开始,您可以通过删除检查和减少迭代来优化代码。唯一的技巧是过滤掉[2, odd_prime, odd_prime]产生偶数的三元组。恕我直言,最简单的方法就是为[2, 2, odd_prime]三胞胎运行一个单独的循环。

def goldbach(limit = 101):
    primes = primes_sieve(limit)
    primes_except_2 = primes[1:]
    primes_len = len(primes_except_2)

    triplets = [[] for i in xrange(limit + 1)]

    # explicitly handle case [2,2,prime]
    # all other cases [2, prime, prime] generate even results
    for ci in xrange(primes_len):
        c = primes_except_2[ci]
        s = 4 + c # 2 + 2 + c
        if s > limit:
            break
        else:
            triplets[s].append([2, 2, c])

    for ai in xrange(primes_len):
        a = primes_except_2[ai]
        for bi in xrange(ai, primes_len):
            b = primes_except_2[bi]
            for ci in xrange(bi, primes_len):
                c = primes_except_2[ci]
                s = a + b + c
                if s > limit:
                    break
                else:
                    triplets[s].append([a, b, c])

    for k, v in enumerate(triplets):
        if len(v) > 0:
            print(str(k) + ':' + str(v))

goldbach(31) 产生以下输出:

7:[[2, 2, 3]]
9:[[2, 2, 5], [3, 3, 3]]
11:[[2, 2, 7], [3, 3, 5]]
13 :[[3, 3, 7], [3, 5, 5]]
15:[[2, 2, 11], [3, 5, 7], [5, 5, 5]]
17:[[2 , 2, 13], [3, 3, 11], [3, 7, 7], [5, 5, 7]]
19:[[3, 3, 13], [3, 5, 11], [ 5, 7, 7]]
21:[[2, 2, 17], [3, 5, 13], [3, 7, 11], [5, 5, 11], [7, 7, 7]]
23:[[2, 2, 19], [3, 3, 17], [3, 7, 13], [5, 5, 13], [5, 7, 11]]
25:[[3, 3 , 19], [3, 5, 17], [3, 11, 11], [5, 7, 13], [7, 7, 11]]
27:[[2, 2, 23], [3, 5, 19], [3, 7, 17], [3, 11, 13], [5, 5, 17], [5, 11, 11], [7, 7, 13]]
29:[[3 , 3, 23], [3, 7, 19], [3, 13, 13], [5, 5, 19], [5, 7, 17], [5, 11, 13], [7, 11 , 11]]
31:[[3, 5, 23], [3, 11, 17], [5, 7, 19], [5, 13, 13], [7, 7, 17], [7, 11, 13] ]

您也可以以类似于仅存储奇数索引(而不存储偶数索引的空列表)的方式优化triplets内部,但我没有打扰。goldbachprimes_sieve

于 2017-06-18T20:31:35.600 回答