The difference between the two cases is explained when the initial PEP for extended unpacking is also taken into account: PEP 3132 -- Extended iterable unpacking .
In the abstracts for this PEP, we see that:
This PEP suggests changing the iterative unpacking syntax to specify the name "catch-all", which will be assigned a list of all elements that are not assigned to a "regular" name.
(my emphasis)
So, in the first case , after execution:
*elements, = iterable
elements will always be a list containing all elements in iterable .
Despite the fact that in both cases it seems similar, * in this case (left side) means: to catch everything that is not assigned a name, and assign it to the selected expression. It works similarly to *args and **kwargs in definitions .
def spam(*args, **kwargs): """ args and kwargs group positional and keywords respectively """
The second case (right side) is slightly different . Here we do not have * working in the "catch everything" mode as much as we do, working as usual in function calls . It expands the contents of the iterable to which it is attached. So the statement:
elements = *iterable,
can be viewed as:
elements = 1, 2, 3, 4,
which is another way to initialize tuple .
Note that a list can be created by simply using elements = [*iterable] , which unpacks the contents of iterable in [] and results in the assignment of the form elements = [1, 2, 3, 4] .
source share