Simple Assignment Operator Become Complicated In Python
Solution 1:
tl;dr: multiple assignments (multiple =
statements on one line) are evaluated from left-to-right, not from right-to-left (after evaluating the right-hand-side expression).
To complicate matters, you are using tuple assignment and 'normal' assignment in a heady mix.
Tuple assignment uses one assignment operator, so to swap two variables, use:
a, b = b, a
The right-hand side must evaluate to a tuple of the same number of elements as there are variables on the left-hand side. You do that, so that's fine.
Now, in your examples, you are not only unpacking tuples. When the left-hand side contains only one variable, the tuple is not unpacked, just simply assigned:
a, b = 1, 2
a = b, a
becomes (2, 1)
.
The fun starts when you use multiple assignments on the same line. These are processed from left to right.
So, the following simple example:
a = b = c = 1
means that a
becomes 1
, then b
, then c
.
Now we can understand each case:
a=a,b=b,c
, wherea = 1
,b = 2
,c = 3
.This becomes: evaluate
b, c
->(2, 3)
, then assign that toa
->a = (2, 3)
. Then assign it toa, b
, soa = 2
,b = 3
. Result:a = 2
,b = 3
,c = 3
.b=a,b=b,c
, wherea = 1
,b = 2
,c = 3
.Same as the case before, but now
b = (2, 3)
is set first, thenb = 3
again, same result as case 1.c=a,b=b,c
, wherea = 1
,b = 2
,c = 3
.Input on the right-hand side the same as cases 1. and 2., but now we first set
c = (2, 3)
. End result as expected,a = 2
,b = 3
,c = (2, 3)
.d=a,b=b,c
, wherea = 1
,b = 2
,c = 3
.Same as case 3. but now we set
d
instead. No surprises.
What confused you here is that the assignments, after the right-hand side has been evaluated, are processed from left to right, not from right to left.
For cases like these, it's actually easiest to run your code (wrapped in a function), through the dis.dis()
function to disassemble the python bytecode:
>>>import dis>>>deff(): a=a,b=b,c...>>>dis.dis(f)
1 0 LOAD_FAST 0 (b)
3 LOAD_GLOBAL 0 (c)
6 BUILD_TUPLE 2
9 DUP_TOP
10 STORE_FAST 1 (a)
13 UNPACK_SEQUENCE 2
16 STORE_FAST 1 (a)
19 STORE_FAST 0 (b)
22 LOAD_CONST 0 (None)
25 RETURN_VALUE
This is the first case; note how after the BUILD_TUPLE
and the DUP_TOP
opcode (the latter creates an extra copy on the stack to serve the extra assignment), the first thing that happens is the STORE_FAST
operation on a
, followed by a UNPACK_SEQUENCE
(the tuple assignment opcode), to then store the results into a
and b
.
Post a Comment for "Simple Assignment Operator Become Complicated In Python"