3 回答
TA貢獻2039條經(jīng)驗 獲得超8個贊
def sieve_primes(stop=10):
L = (x for x in range(2, stop+1))
while True:
prime = next(L)
L = filter(lambda x: x % prime != 0 or x == prime, L)
yield prime
您的代碼中到底發(fā)生了什么在下面逐次迭代中給出。為方便起見,我在第一次迭代中將 L 表示為 L1,在第二次迭代中將 L 表示為 L2,依此類推。
在第一次迭代
prime=next(L)中為 2(如預(yù)期的那樣)。L1=filter(lambda x: x % prime != 0 or x == prime, L)(的值L是惰性計算的,即僅根據(jù)需要計算的值。yield prime將產(chǎn)生2預(yù)期的結(jié)果。在第二次迭代
prime=next(L1)中。棘手的部分來了。L1是filter object其值僅按需計算。因此,在第二次迭代中,當prime=next(L1)執(zhí)行時,僅計算一個值L?,F(xiàn)在 lambda 使用 prime as2并計算一個值,即3(3%2!=0) ,即 nowprime。L2=filter(lambda x: x % prime != 0 or x == prime, L1)(的值L2是惰性計算的,即僅按需計算的值。現(xiàn)在您yield prime將屈服3。在第三次迭代
prime=next(L2)中。現(xiàn)在事情變得有點復雜了。要從中獲得一個值,L2您需要計算一個值,L1而要計算一個值L1,您需要計算一個值L。如果你沒記錯的話L,現(xiàn)在將 yield4它將被用于L1產(chǎn)生一個值。但最新的參考prime是3.4%3!=0被評估為True。所以,L1產(chǎn)量4。因此,計算要產(chǎn)生的值L24%3!=0is 評估為Truesoprime=next(L2)is4。
對進一步的迭代應(yīng)用相同的邏輯,您會發(fā)現(xiàn) 5,6,7,8,9... 將在進一步的迭代中產(chǎn)生。
TA貢獻1789條經(jīng)驗 獲得超8個贊
您prime在 lambda 中使用變量,這是您從封閉范圍繼承的引用。當您的代碼評估 lambda 時,它將使用在繼承引用的范圍內(nèi)綁定到該引用的任何值。當您不使用tee和評估列表時,所有 lambda 函數(shù)都是相同的,并且對prime.
tee工作原理是將結(jié)果存儲在一個列表中,并在您稍后再次詢問時從該列表中將它們提供給您,因此對于它的每個值prime實際上將過濾器應(yīng)用于來自的所有值L
prime您可以通過在 的范圍內(nèi)綁定來解決此問題,方法lambda是將其作為具有默認值的參數(shù)傳遞。這將該值保存為函數(shù)對象的一部分,prime然后引用是對該存儲值的本地引用。
TA貢獻1799條經(jīng)驗 獲得超9個贊
def sieve_primes(stop=10):
L = (x for x in range(2, stop+1))
while True:
prime = next(L)
L = filter(lambda x: x % prime != 0 or x == prime, L)
yield prime下面的呢?使用生成器表達式通常比使用 map/filter/reduce 更好。
#!/usr/bin/env python3
def sieve_primes(stop=100):
primes = []
for candidate in range(2, stop+1):
if not any(candidate % prime == 0 for prime in primes):
primes.append(candidate)
yield candidate
for prime in sieve_primes():
print(prime)
添加回答
舉報
