[Python-Dev] PEP 479: Change StopIteration handling inside generators
Steven D'Aprano
steve at pearwood.info
Fri Nov 21 16:58:00 CET 2014
On Sat, Nov 22, 2014 at 12:53:41AM +1100, Chris Angelico wrote:
> On Sat, Nov 22, 2014 at 12:47 AM, Raymond Hettinger
> <raymond.hettinger at gmail.com> wrote:
> > Also, the proposal breaks a reasonably useful pattern of calling
> > next(subiterator) inside a generator and letting the generator terminate
> > when the data stream ends. Here is an example that I have taught for
> > years:
> >
> > def izip(iterable1, iterable2):
> > it1 = iter(iterable1)
> > it2 = iter(iterable2)
> > while True:
> > v1 = next(it1)
> > v2 = next(it2)
> > yield v1, v2
>
> Is it obvious to every user that this will consume an element from
> it1, then silently terminate if it2 no longer has any content?
"Every user"? Of course not. But it should be obvious to those who think
carefully about the specification of zip() and what is available to
implement it.
zip() can't detect that the second argument is empty except by calling
next(), which it doesn't do until after it has retrieved a value from
the first argument. If it turns out the second argument is empty, what
can it do with that first value? It can't shove it back into the
iterator. It can't return a single value, or pad it with some sentinel
value (that's what izip_longest does). Since zip() is documented as
halting on the shorter argument, it can't raise an exception. So what
other options are there apart from silently consuming the value?
Indeed that is exactly what the built-in zip does:
py> a = iter("abcdef")
py> b = iter("abc")
py> list(zip(a, b))
[('a', 'a'), ('b', 'b'), ('c', 'c')]
py> next(a)
'e'
--
Steven
More information about the Python-Dev
mailing list