1

I want to write a programme which removes all the primes which contain an even digit from a list of primes.

Can anyone explain why this code returns the correct result if the limit = 200, but returns an error if the limit = 300?

def odd_primes(limit):
    r = list(gen_primes(limit))
    for i in r[:]:
        for j in str(i):
            if int(j)%2==0:
                r.remove(i)
return r

Where gen_primes(limit) is a generator which returns all primes under limit.

If limit = 200 it returns:

[3, 5, 7, 11, 13, 17, 19, 31, 37, 53, 59, 71, 73, 79, 97, 113, 131, 137, 139, 151, 157, 173, 179, 191, 193, 197, 199]

But if the limit is 300 I get this error:

line 19, in odd_primes
r.remove(i)
ValueError: list.remove(x): x not in list

Why is this the case? And how can I correct it?

Anthon
  • 69,918
  • 32
  • 186
  • 246
ggordon
  • 259
  • 1
  • 3
  • 16

2 Answers2

5

Your code may remove the same element multiple times, if it contains multiple even digits. The first such prime is 223, which is why your code fails when limit is 300, but not when it's 200.

This is the offending code:

for j in str(i):
    if int(j)%2==0:
        r.remove(i)

Instead, just remove the prime once. For example:

for j in str(i):
    if int(j)%2==0:
        r.remove(i)
        break

Or perhaps more stylishly:

if any(int(j)%2 == 0 for j in str(i)):
    r.remove(i)
Paul Hankin
  • 54,811
  • 11
  • 92
  • 118
2

If your prime has two even numbers your routine tries to remove it twice. I would do:

def odd_primes(limit):
    r = list(gen_primes(limit))
    for i in r[:]:
        for j in str(i):
            if j in '02468':
                r.remove(i)
                break
    return r
Anthon
  • 69,918
  • 32
  • 186
  • 246