2
我試圖使用Sieve of Eratosthenes算法實現素數生成器。我這樣做只是嘗試使用遞歸iterator merging來實現篩選器。合併迭代器產生難以理解的結果
我做到這一點:
from itertools import count,islice,groupby
from heapq import merge
def primes3():
p = 2
yield p
sifter = (i*p for i in count(p))
s = next(sifter)
for p in count(p+1):
if p==s: # this p is sieved out
print('s: {}'.format(s))
s = next(sifter)
else:
yield p # this is prime
print('p: {}'.format(p))
sifter = (k for k, g in groupby(merge(sifter,(i*p for i in count(p))))) #add this serie to the sifter: p*p, p*(p+1), p*(p+2), ...
print(list(islice(primes3(),10)))
輸出是:
p: 3
s: 4
p: 5
p: 6
p: 7
p: 8
p: 9
p: 10
p: 11
s: 12
[2, 3, 5, 6, 7, 8, 9, 10, 11, 13]
第一個數字被篩分爲4
。但接下來是12
,而不是6
,因爲它應該是。這是爲什麼?我用下面的代碼檢查的話:
>>> sifter = (i*2 for i in count(2))
>>> next(sifter)
4
>>> sifter = (k for k, g in groupby(merge(sifter,(i*3 for i in count(3)))))
>>> print(list(islice(sifter,20)))
[6, 8, 9, 10, 12, 14, 15, 16, 18, 20, 21, 22, 24, 26, 27, 28, 30, 32, 33, 34]
所以,我們可以看出,在試驗條件篩得到正確的結果。
我在哪裏犯錯?我認爲這一定是微不足道的,我只是看不到。
謝謝!沒有你的幫助,我懷疑我會發現什麼是錯的! – ovgolovin
還有一個問題。除了創建特殊函數之外,是否還有另一種方法可以創建局部範圍(因爲函數調用有點慢,據我所知)? – ovgolovin
除了'gensifter'函數外,我還發現了另一個解決方案:'count(p * p,p)'(因爲第一個參數是一個起始值,第二個參數是步長) – ovgolovin