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.
Introduction. Unpacking in Python refers to an operation that consists of assigning an iterable of values to a tuple (or list ) of variables in a single assignment statement. As a complement, the term packing can be used when we collect several values in a single variable using the iterable unpacking operator, * .
Python tuples are immutable means that they can not be modified in whole program. Packing and Unpacking a Tuple: In Python, there is a very powerful tuple assignment feature that assigns the right-hand side of values into the left-hand side. In another way, it is called unpacking of a tuple of values into a variable.
Multiple assignment (also known as tuple unpacking or iterable unpacking) allows you to assign multiple variables at the same time in one line of code. This feature often seems simple after you've learned about it, but it can be tricky to recall multiple assignment when you need it most.
Unpacking tuples means assigning individual elements of a tuple to multiple variables. Use the * operator to assign remaining elements of an unpacking assignment into a list and assign it to a variable.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With