[Python-Dev] PEP 479: Change StopIteration handling inside generators
Paul Moore
p.f.moore at gmail.com
Fri Nov 21 17:14:58 CET 2014
On 21 November 2014 15:58, Steven D'Aprano <steve at pearwood.info> wrote:
>> > 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?
Interestingly, although I said "yes, it's obvious", I'd missed this
subtlety. But I don't consider it "unexpected" or a "gotcha", just
subtle. I certainly don't consider it to be the *wrong* behaviour - on
the contrary, I'd be more surprised to get a RuntimeError when the
second iterator was shorter.
What I understand to be the recommended alternative:
def izip(iterable1, iterable2):
it1 = iter(iterable1)
it2 = iter(iterable2)
while True:
try:
# Is it OK to cover both statements with one try...except?
# I think it should be, but it's a pattern I try to avoid
v1 = next(it1)
v2 = next(it2)
except StopIteration:
return
yield v1, v2
looks less obvious to me, and obscures the intent a little.
(Note that I understand this is only one example and that others
present a much more compelling case in favour of the explicit return
form)
Paul
More information about the Python-Dev
mailing list