6
[パイソン3.4]シンプルエラトステネス篩で以下のプログラム:Pythonジェネレータ。 2つの明らかに同一のプログラムが異なる動作
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を生成します]。 OK。 excl()をインライン化し、呼び出しをコメントする行のコメントを外して、[2,3,4,5,6,7,8,9,10,11]とします。どうして?
ループを反復するループ内でシーケンスを変更するときに問題が発生することはありますか?
ありがとうございます。
私はこの回答を理解しているかどうかはわかりません。素数はexcl(gen.expression)では変更されず、ループ内で変更され、このコンテキストはインライン化された 'call'バージョンと同じです。私はfilter()について間違った発言を削除しました。 –
@JerzyKarczmarczuk [PEP 227](https://www.python.org/dev/peps/pep-0227/)によれば、名前がコードブロック(ネストされた関数)内で使用されていてもそこにバインドされていないグローバルに宣言されていない場合は、**最も近い包囲関数領域への参照として扱われます。あなたのケースに当てはまるように、ジェネレータ式はフードの下の関数であり、変数 'pr'を定義しないので、' pr'は囲み関数の 'pr'の**参照**です'ふるい ')。つまり、 'sieve 'の' pr'が変更されると、ジェネレータ表現の 'pr'も変わります。 – ppperry