python: умножение для цикла пропущено на второй итерации
Я пытаюсь реализовать Sieve of Euler (как описано на сайте softwarepraxis.com). У меня есть код, который отлично работает на первой итерации, однако на следующей итерации мое умножение по какой-то причине пропускается, что ускользает от меня (вероятно, просто пропускает какой-то Python Поведение там, что является здравым смыслом для более опытного программиста) Я запускаю это:
import numpy as np
#set up parameters
primes = [2]
startval = 2
stopval = 10000
firstrun = True
candidates = np.arange(start=startval,stop=stopval+1,step=1)
#actual program
for idx in range(int(np.ceil(np.sqrt(stopval)))): #only up until sqrt(n) needs checking
print('pos1')
print(candidates)
print(candidates[0])
times = candidates[0]*candidates
print(times)
diffset = list(set(candidates)^set(times))
if len(diffset) is not 0: #to make sure the program quits properly if diffset=[]
primes.append(diffset.pop(0))
print('pos2')
print(diffset)
candidates = diffset
print('pos3')
print(candidates)
else:
break
print(primes)
Различные операторы печати просто так, чтобы я мог понять, что происходит. Обратите внимание, что первые выходы в порядке, интересная часть начинается во второй раз, когда печатается pos1. мои кандидаты обновляются так, как я хочу, новый первый элемент также является правильным. Итак, мой вопрос:
Почему times = candidates[0]*candidates
видимо пропустили на второй итерации?
Пожалуйста, обратите внимание: я не прошу ответа "поцарапайте ваш код, скопируйте этот рабочий и более быстрый, лучший, приятный код". Существует множество реализаций Python, я хочу сделать это сам. Я думаю, что мне не хватает довольно важной концепции Python, и именно поэтому мой код не ведет себя.
(Если кто-нибудь спросит: "Нет, это не домашнее задание. Я использую немного Python на своем рабочем месте и люблю делать такие вещи дома, чтобы улучшить свои навыки кодирования")
1 ответ
Я только что запустил твой код. Глядя на вывод times
в строке 14 вы можете видеть, что после первой итерации операция выполняется, но не так, как вы хотели. Список times
это всего лишь три раза в списке candidates
ставить друг за другом. Разработать:
1-я итерация
candidates = np.arange(start=startval,stop=stopval+1,step=1)
таким образом, кандидаты это массив NumPy. дела
candidates*candidates[0]
такой же как candidates*2
, который является "numpy_array * number", который является просто поэлементным умножением. Теперь дальше вниз вы делаете
diffset = list(set(candidates) ^ set(times))
....
candidates = diffset
который устанавливает:
2-я итерацияcandidates
теперь список (см. выше). дела
candidates*candidates[0]
просто candidates*3
который теперь является "list*number", что в python не "умножить каждый элемент списка на число", а вместо этого: "создать новый список как исходный список, объединенный несколько раз с самим собой". Вот почему вы не видите ожидаемого результата.
Чтобы это исправить, просто сделайте:
candidates = np.array(diffset)