Re: [Python-Dev] PEP 479: Change StopIteration handling inside generators

2014年11月21日 08:16:33 -0800

On 21 November 2014 15:58, Steven D'Aprano <[email protected]> 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
_______________________________________________
Python-Dev mailing list
[email protected]
https://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
https://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com

Reply via email to