Reputation: 362657
L = [0, 1, 2]
L[::2], *rest = "abcdef"
print(L, rest)
Expected output:
['a', 1, 'b'] ['c', 'd', 'e', 'f']
Actual output:
ValueError: attempt to assign sequence of size 1 to extended slice of size 2
Is using unpacking assignment in combination with extended slice assignment not possible for some reason? Why? I don't see anything obvious in PEP 3132 -- Extended Iterable Unpacking or in the Python datamodel suggesting this shouldn't be valid.
Upvotes: 5
Views: 333
Reputation: 106543
This is not a bug. Unpacking is always done by mapping each item in the right-hand iterable to the corresponding comma-separated left-hand expression when there are more than one left-hand expressions. The L[::2]
expression in your example is just one of the two left-hand expressions, and it therefore receives just one item from unpacking the right-hand iterable while the starred left-hand expression receives the rest.
As the rationale in PEP-3132 points out:
Many algorithms require splitting a sequence in a "first, rest" pair. With the new syntax,
first, rest = seq[0], seq[1:]
is replaced by the cleaner and probably more efficient:
first, *rest = seq
your:
L[::2], *rest = "abcdef"
is therefore equivalent to:
L[::2], rest = "a", "bcdef"
which would thus result in the said error of ValueError: attempt to assign sequence of size 1 to extended slice of size 2
since "a"
cannot be further unpacked for a slice of 2.
If Python were to add your interpretation of unpacking into the syntax, it can make, for example, the statement of:
L[::2], *rest = "ab", "c", "d"
ambiguous--should L
become ["a", 1, "b"]
and rest
become ["c", "d"]
, or should L
become ["ab", 1, "c"]
, and rest
become ["d"]
? Always allotting one item in the iterable per LHS expression makes the interpretation much clearer and less prone to runtime errors.
Upvotes: 6