简体   繁体   中英

Why do I need trailing comma in multiple assignment / unpacking?

CASE 1 code in below works well

d, c, b, *a = 5, 4, 3, 1, 2
print(type(a), a)
print(type(b), b)
print(type(c), c)
print(type(d), d)

Results

   <class 'list'> [1, 2]
   <class 'int'> 3
   <class 'int'> 4
   <class 'int'> 5

CASE 2 But as soon as i remove d,c,b and keep only *a then its ERROR;

 *a =  1, 2
print(type(a), a)

    *a =  1, 2
    ^
SyntaxError: starred assignment target must be in a list or tuple

CASE 3 i have to put comma in last to make it work But in CASE 1 it worked as their *a was in last as well

*a, =  1, 2
print(type(a), a)
<class 'list'> [1, 2]

My understanding is;

* a -- This itself mean that pack the right side of elements and create a list. why its looking for "," in last?

*a is not looking for a list. It's looking for an arbitrary number of elements inside a list or a tuple. It then stores those elements in a list.

In an expression like [a, *b] = [0, 1, 2, 3] , There is a list unpacking, trying to match two lists , matching each nth element of a list to one corresponding element of the other. However if the nth element of the left hand side has a star, it will instead be able to match to several elements of the right hand side and it will store those elements as a list of a.

In *a = [0, 1, 2, 3] , a is trying to be matching multiple elements from... nothing? There are no list patterns on the left hand side *a can feed from. If you want to match several elements of the right hand side, you must do a list or tuple unpacking:

[*a] = [0, 1, 2, 3] # left hand side is a list unpacking
(*a,) = [0, 1, 2, 3] # left hand side is a tuple unpacking
*a, = [0, 1, 2, 3] # left hand side is still a tuple unpacking
*a = [0, 1, 2, 3] # error, left hand size is not an unpacking as it doesn't have a list or tuple pattern so *a is meaningless

1, 2 is already a tuple. To assign it to a, you just need a = 1, 2 . To assign a list, do a = [1, 2] .

correct, and agreed with above point. In case of *a = 1, 2 , I would argue is misguided, being as the value 1, 2 is already a tuple. Thus, with this basically is saying, unpack the tuple 1, 2 due to * and get me all of it, the packed value that is, into a new unpacked tuple and I want the 1, 2 . Thus, double legwork for real no effect other than stylistic appeal I guess.

Interestingly, observe this:

>>> _, *a = 1, 2, ...
>>> a
[2, Ellipsis]
>>> _, *a = 1,
>>> a
[]

Where the _ is synonymous for, discard that initial unpacked value.


Btw: I guess you could also similarly expect *a = 1 to unpack into list [1] , but that don't work neither. I guess you likely wanting a = 1, with the trailing comma at end - see that it's the same characters count too.

To get a list : You truthfully right. I didn't know about the *a, = 1, - but it's cool that it work "Like That ™️":

>>> _, *_ = 1,
>>> _
[]
>>> a = 1,
>>> a
(1,)
>>> *_, = 1,
>>> _
[1]

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM