6
下面[Python的3.4]是一個簡單的埃拉託塞尼篩的程序:Python生成器;兩個明顯相同的程序的工作方式不同
from itertools import *
def excl(ns,pr):
return (i for i in ns if i%pr)
def sieve(ns):
while True:
pr=next(ns)
yield pr
ns=excl(ns,pr)
# ns=(i for i in ns if i%pr)
r=list(islice(sieve(count(2)),10))
產生[2,3,5,7,11,13,17,19,23,29 ]。好。取消註釋excl()和評論該調用的行,給出[2,3,4,5,6,7,8,9,10,11]。爲什麼?
它是否與在迭代它的循環內執行序列時期望的麻煩有關?
謝謝你的任何提示。
我不確定我是否理解這個答案。素數不會在excl(也不在gen.expression)中改變,它在循環內發生變化,並且此內容對於內聯和「調用」版本而言是相同的。順便說一句,我刪除了關於filter()的錯誤評論。 –
@JerzyKarczmarczuk根據[PEP 227](https://www.python.org/dev/peps/pep-0227/),如果在代碼塊(嵌套函數)中使用名稱,但它不在那裏綁定並且未聲明爲全局函數,則將該用法視爲對最近的函數區域的引用。由於它適用於你的情況,生成器表達式是引擎蓋下的一個函數,它不定義變量'pr',因此它的'pr'是封閉函數中的'pr'的**引用**( 'sieve')。這意味着當'sieve'中的'pr'改變時,發生器表達式中的'pr'也會改變。 – ppperry