2013-07-01 3 views
1

Я пытаюсь создать первичное сито в Python.Python list.remove for loop "x not in list"

Я начинаю с составления списка от 2 до 2000. Я хочу перебрать все простые числа с помощью проверки и удалить все кратные простых чисел из списка.

Я еще не получил цикл для простых чисел, но у меня есть способ начать с номера 2 и удалить все его кратные.

primes=list(range(2,2001)) 
p=2 

while p<len(primes): 
    for x in range (p*p, len(primes), p): 
     primes.remove(x) 
    print(primes) 

это печатает: [...] 1989, 1991, 1993, 1995, 1997, 1999, 2000]

Как вы можете видеть, номер 2000 по-прежнему существует, и это не должно быть ,

Traceback (most recent call last): 
    File "C:/Users/Are/PycharmProjects/Project Euler/10.py", line 8, in <module> 
    primes.remove(x) 
ValueError: list.remove(x): x not in list 

Что случилось с моими рассуждениями?

Я использую PyCharm, есть ли способ для меня распечатать значение для x во время ошибки?

ответ

4

Вы создать список 1999 элементов:

>>> len(range(2,2001)) 
1999 

Вы затем цикл над range() до, но не включая, что длина:

for x in range (p*p, len(primes), p): 

Таким образом x никогда не будет больше, чем 1998

Вместо len(primes), используйте верхний предел константы:

limit = 2001 
primes=list(range(limit)) 

# ... 

for x in range (p*p, limit, p): 

Следующая проблема заключается в том, что вы по-прежнему цикла с while p<len(primes):; вы будете генерировать числа, которые уже не часть списка primes, поэтому их нельзя удалить во второй раз. Вы можете использовать обработчик исключений поймать исключение:

try: 
    primes.remove(x) 
except ValueError: 
    # already removed 
    pass 

но вы можете пересмотреть условия в while цикла.

+0

Отлично. Да, как я писал другому парню, я удалил цикл while, это создало проблемы, потому что программа еще не перешла к следующему премьеру. Ошибка исчезла, и мой список сохранил 2 и удалил все свои кратные. Отлично. Спасибо за обработку исключений, я этого не делал раньше, всегда узнавая больше. Еще раз спасибо. – DrOnline

5

ваш список не 2000 долго, вы начинаете в 2 ..

>>> primes=list(range(2,2001)) 
>>> print len(primes) 
1999 

Итак, когда вы делаете то время цикла, он не получает до 2000 ... :)

2

В range(a,b) первое значение: a, а последнее значение - b-1. В вашем случае это означает, что вы выполняете только итерацию до len(primes)-1, что меньше 2000.

1

Значение x во время сбоя фактически 4. Вы не увеличиваете p до следующего значения в списке в конце первого цикла.

Во-вторых, вы пытаетесь удалить значения несколько раз из списка. Вы, например, попытаетесь удалить 12 дважды. Однажды, когда вы повторяете 2, один раз, когда вы повторяете 3.

Наконец, вы идете по длине списка, который всегда уменьшается, когда вы удаляете из него значения. Ваш первый раз вокруг цикла и ваш размер списка очень малы.

Переделка код:

primes=list(range(2,2001)) 
p=2 

while p<2000: 
    for x in range (p*p, 2001, p): 
     if x in primes: 
      primes.remove(x) 
    while 1: 
     p = p + 1 
     if p in primes or p > 2000: 
      break 

print primes 
+0

Ах, что, хотя должно быть удалено, это не имеет смысла, пока программа не будет завершена, нормально, это решило. большое спасибо. – DrOnline

+0

Хорошо, я обновил сообщение с помощью примера программы – OmnipotentEntity