Ответ 1
Я должен согласиться, этот материал иногда может быть очень запутанным (но приятная головоломка!).
Оказывается, ваш итератор sifter
изменяется при изменении значения p
(кстати, я использую python 2.6.5 для проверки этого, а не python 3, поэтому синтаксис печати немного отличается):
>> p = 2
>> sifter = (i*p for i in count(p))
>> for x in range(3):
>> print next(sifter)
4
6
8
>>> # now lets see what happens when we change p
>>> p = 3
>>> for x in range(3):
>>> print next(sifter)
15
18
21
Итак, часть тетера i*p
оценивается с помощью new из p, как только p обновляется. P действительно обновляется в вашем mainloop, поэтому вы не получите ожидаемого результата.
Существует простой способ решить эту задачу: создать функцию для генерации итератора ситтера таким образом, чтобы итератор не был привязан к p:
def gensifter(x):
return (i*x for i in count(x))
и поместите это в свой код (опять же, я преобразовал его в python 2.6.5):
def primes3():
p = 2
yield p
sifter = gensifter(p) # <-- changed!
s = next(sifter)
for p in count(p+1):
#print '(testing p = %d\ts = %d)' % (p, s)
if p==s: # this p is sieved out
print 's:', s
s = next(sifter)
else:
yield p # this is prime
print 'p:', p
sifter = (k for k, g in groupby(merge(sifter,gensifter(p)))) # <-- changed!
Теперь посмотрим на результат:
>>> print list(islice(primes3(), 10))
p: 3
s: 4
p: 5
s: 6
p: 7
s: 8
s: 9
s: 10
p: 11
s: 12
p: 13
s: 14
s: 15
s: 16
p: 17
s: 18
p: 19
s: 20
s: 21
s: 22
p: 23
s: 24
s: 25
s: 26
s: 27
s: 28
[2, 3, 5, 7, 11, 13, 17, 19, 23, 29]
Природы в изобилии!