Reputation: 47
I am pretty new to Python and struggle to count my amount of equal sums in my list of lists. I create a list of numbers (list oneven), according to Goldbach every number is equal to three Primenumbers. I now have a list of all combination of prime numbers, now I want to count the amount of combinations that every number in list oneven has, and print it out. I tried using "import Collections" which wouldn't work due to my code not being hashable. Then I tired adding a number to an empty list which rises to the equal sums but I get the error message:
IndexError: list assignment index out of range
Here is my code with which I am struggling:
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)
Incase you are interested in what I am trying to do, I am trying to write a counter for Goldbachs theory, so here is my entire Code:
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)
At the end it should look a bit like this:
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,
Upvotes: 0
Views: 95
Reputation: 23788
There a few places where your code is rather inefficient. First of all, if you know the top limit of the primes you'll need, then Sieve of Eratosthenes is a much more efficient way to generate primes:
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
Then your loops with inner checks if a >= b:
and if c in priemgetallen and b >= c:
are very inefficient. It is much more efficient to iterate through primes with 3 nested loops, get sum and add it to the corresponding "bin". Also by remembering current index in the "outer" iteration and starting from it you can optimize your code by both removing the check and iterating less. The only trick is to filter out triplets of form [2, odd_prime, odd_prime]
that produce even numbers. IMHO the easiest way to do it is just to run a separate loop for [2, 2, odd_prime]
triplets.
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) produces following output:
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]]
You may also optimize triplets
inside goldbach
in a way similar to the one used in primes_sieve
to store only odd indices (and not store empty lists for even ones) but I didn't bother.
Upvotes: 0