Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    text
    copied!<p><strong>EDIT</strong>: Use <code>itertools.islice</code>. The pattern below that I originally proposed is bad idea — it crashes when <code>it</code> yields less than <code>n</code> values, and this behaviour depends on subtle issues, so people reading such code are unlikely to understand it's precise semantics.</p> <blockquote> <p>There is also</p> <pre><code>[next(it) for _ in range(n)] </code></pre> <p>which might(?) be clearer to people not familiar with itertools; but if you deal with iterators a lot, itertools is a worthy addition to your toolset.</p> </blockquote> <h3>What happens if <code>next(it)</code> was exhausted and raises <code>StopIteration</code>?</h3> <p>(i.e. when <code>it</code> had less than <code>n</code> values to yield)</p> <p>When I wrote the above line a couple years ago, I probably thought a <code>StopIteration</code> will have the clever side effect of cleanly terminating the list comprehension. But no, the whole comprehension will crash passing the <code>StopIteration</code> upwards. (It'd exit cleanly only if the exception originated from the <code>range(n)</code> iterator.)</p> <p>Which is probably not the behavior you want.</p> <p>But it gets worse. The following is supposed to be equivalent to the list comprehension (especially on Python 3):</p> <pre><code>list(next(it) for _ in range(n)) </code></pre> <p>It isn't. The inner part is shorthand for a generator function; <code>list()</code> knows it's done when it raises <code>StopIteration</code> <em>anywhere</em>.<br> => This version copes safely when there aren't <code>n</code> values and returns a shorter list. (Like <code>itertools.islice()</code>.)</p> <p>[Executions on: <a href="https://ideone.com/KJeZii" rel="nofollow noreferrer">2.7</a>, <a href="https://ideone.com/KJeZii" rel="nofollow noreferrer">3.4</a>]</p> <p>But that's too going to change! The fact a generator silently exits when any code inside it raises <code>StopIteration</code> is a known wart, addressed by <a href="https://www.python.org/dev/peps/pep-0479/" rel="nofollow noreferrer">PEP 479</a>. From Python 3.7 (or 3.5 with a future import) that's going to cause a <code>RuntimeError</code> instead of cleanly finishing the generator. I.e. it'll become similar to the list comprehension's behaviour. (Tested on a recent HEAD build)</p>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload