
On Tue, Nov 28, 2017 at 01:14:40AM +1100, Chris Angelico wrote:
Nah, far easier:
x, y = iter(it)
since that'll be a no-op in the first case
Not necessarily a no-op. __iter__ might have side-effects. Of course if you can guarantee that you ONLY have iterators, then there's no need to test for an iterator. But it isn't always appropriate to convert sequences to an iterator. And besides, if you're going to call iter(), that's not that much shorter than islice() (assuming you've already imported it, of course). You only save five characters or so. But the big problem here is that iterable unpacking would be conceptually split into "iterator unpacking" and "all other iterables unpacking". I think that's unnecessary complication.
I do think islice is verbose, but the main problem is that you have to match the second argument to the number of assignment targets.
Yes, there is a certain amount of redundancy in having to specify the number of items in a slice, using either syntax: a, b = sequence[:2] a, b = islice(iterable, 2) but it is minimal duplication, hardly the sort of thing DRY is concerned with: http://www.artima.com/intv/dry.html and there is an equally important principle that is satisfied by being explicit about the number of items you want. (In the face of ambiguity, refuse the temptation to guess.) If you get the number wrong, you will find out immediately. And the fix is trivial. In this case, there is a small but real benefit to counting the assignment targets and being explicit about the number of items to slice. Consider an extension to this "non-consuming" unpacking that allowed syntax like this to pass silently: a, b = x, y, z That ought to be a clear error, right? I would hope you don't think that Python should let that through. Okay, now we put x, y, z into a list, then unpack the list: L = [x, y, z] a, b = L That ought to still be an error, unless we explicity silence it. One way to do so is with an explicit slice: a, b = L[:2] This isn't repeating yourself, it isn't really duplicated or redundant information. It is telling the interpreter, and more importantly the reader, that you want exactly two items out of a list that could contain any arbitrary number of items and that you are planning to bind them to exactly two targets. Same goes if we use islice(iterable) instead. Another way would be special syntax to say you want non-consuming unpacking, swapping out the "ambiguity" Zen for the "explicitly silencing errors" Zen. So I really don't see this as anything more than, at best, a fairly minor piece of syntactic sugar. It doesn't really add anything to the language, or allow us to do anything cool we couldn't do before. -- Steve