cvitkovm cvitkovm - 3 months ago 9
Python Question

Python Multiple Assignment Statements In One Line

(Don't worry, this isn't another question about unpacking tuples.)

In python, a statement like

foo = bar = baz = 5
assigns the variables foo, bar, and baz to 5. It assigns these variables from left to right, as can be proved by nastier examples like

>>> foo[0] = foo = [0]
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
NameError: name 'foo' is not defined
>>> foo = foo[0] = [0]
>>> foo
[[...]]
>>> foo[0]
[[...]]
>>> foo is foo[0]
True


But the python language reference states that assignment statements have the form

(target_list "=")+ (expression_list | yield_expression)


and on assignment the
expression_list
is evaluated first and then the assigning happens.

So how can the line
foo = bar = 5
be valid, given that
bar = 5
isn't an
expression_list
? How are these multiple assignments on one line getting parsed and evaluated? Am I reading the language reference wrong?

Answer

All credit goes to @MarkDickinson, who answered this in a comment:

Notice the + in (target_list "=")+, which means one or more copies. In foo = bar = 5, there are two (target_list "=") productions, and the expression_list part is just 5

All target_list productions (i.e. things that look like foo =) in an assignment statement get assigned, from left to right, to the expression_list on the right end of the statement, after the expression_list gets evaluated.

And of course the usual 'tuple-unpacking' assignment syntax works within this syntax, letting you do things like

>>> foo, boo, moo = boo[0], moo[0], foo[0] = moo[0], foo[0], boo[0] = [0], [0], [0]
>>> foo
[[[[...]]]]
>>> foo[0] is boo
True
>>> foo[0][0] is moo
True
>>> foo[0][0][0] is foo
True
Comments