(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?
All credit goes to @MarkDickinson, who answered this in a comment:
Notice the
+
in(target_list "=")+
, which means one or more copies. Infoo = bar = 5
, there are two(target_list "=")
productions, and theexpression_list
part is just5
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