<pre><code>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
</code></pre>
<p>下面一次又一次地给出了代码中发生的具体情况。为了方便起见,我在第一次迭代中将L表示为L1,在第二次迭代中将L表示为L2,依此类推</p>
<ul>
<li><p>在第一次迭代中<code>prime=next(L)</code>为2(如预期)。
<code>L1=filter(lambda x: x % prime != 0 or x == prime, L)</code>(延迟计算<code>L</code>的值,即仅按需计算。<code>yield prime</code>将产生<code>2</code>预期值。</p></li>
<li><p>在第二次迭代中<code>prime=next(L1)</code>。棘手的部分来了。<code>L1</code>是只根据需要计算值的<code>filter object</code>。因此,在第二次迭代中,当执行<code>prime=next(L1)</code>时,只从<code>L</code>计算一个值。现在lambda使用素数作为<code>2</code>,并计算一个值,即<code>3</code>(<code>3%2!=0</code>),即现在的<code>prime</code>(延迟计算<code>L2</code>的值,即仅按需计算值。现在<code>yield prime</code>将产生<code>3</code>。</p></li>
<li><p>在第三次迭代中<code>prime=next(L2)</code>。现在事情变得有点复杂。要从<code>L2</code>中得到一个值,需要计算<code>L1</code>的一个值,要计算一个值<code>L1</code>,需要计算一个值<code>L</code>。如果你没记错<code>L</code>现在将产生<code>4</code>,现在<code>L1</code>将使用它产生一个值。但是对<code>prime</code>的最新引用是<code>3</code>。<code>4%3!=0</code>被计算为<code>True</code>。因此,<code>L1</code>产生<code>4</code>。因此,计算<code>L2</code>{<cd29>}产生的值是<code>True</code>所以<code>prime=next(L2)</code>产生的值是<code>4</code>。</p></li>
</ul>
<p>在进一步的迭代中应用相同的逻辑,你会发现5,6,7,8,9…将在进一步的迭代中产生</p>