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