ValueError vs IndexError, unpacking arguments with string.split

Chris Angelico rosuav at gmail.com
Sat Dec 1 20:20:32 EST 2018


On Sun, Dec 2, 2018 at 11:55 AM Morten W. Petersen <morphex at gmail.com> wrote:
>
> On Sat, Dec 1, 2018 at 1:11 AM Chris Angelico <rosuav at gmail.com> wrote:
>>
>> On Sat, Dec 1, 2018 at 10:55 AM Morten W. Petersen <morphex at gmail.com> wrote:
>> > But this raises the question of how to write Python code,
>> > short and sweet, that could handle infinite iterators in
>> > such an unpack with multiple variables to assign to.
>> >
>> > Which I guess is mostly theoretical, as there are other
>> > ways of designing code to avoid needing to unpack
>> > an infinite iterator using the * prefix.
>>
>> It could only be done with the cooperation of the iterable in
>> question. For instance, a range object could implement a "remove
>> first" operation that does this, and several itertools types wouldn't
>> need to change at all. But it can't be done generically other than the
>> way it now is (pump the iterator the rest of the way).
>
> I wasn't able to follow this, could you elaborate?
>

The way *x works in unpacking is that the entire iterable gets
unpacked, and everything gets put into a list that is then assigned to
x. This is generic, works on any iterable, but doesn't take advantage
of anything. Consider:

>>> x = range(3, 20, 5)
>>> first, *rest = x
>>> first
3
>>> rest
[8, 13, 18]

If a range object were asked to yield its first-and-rest in this way,
it could instead return range(8, 20, 5) - add the step onto the start,
job done. Same if you ask for some off the beginning and some off the
end And with a number of the itertools iterables/iterators, the "rest"
wouldn't actually need to change anything, since the iterator will get
consumed. This would need explicit support from the iterable, though,
as Python can't know how to do this generically; so there would need
to be a protocol for "unpack".

ChrisA



More information about the Python-list mailing list