There is a difference. When on the same line, both values will be updated concurrently, while on different lines no. How a
starts at zero and b
in a, when you do a, b = b, a+b
, a
will receive the value of b
, 1, and b
will receive the value of a+b
, 0+1=1. Note that the value of a
is still 0 on this line as it will be 1 only after the entire line is executed. In separate lines, b
would receive 1+1=2, breaking the sequence.
In the same vein:
a = 0
b = 1
print('Antes:')
print('a', a) # a 0
print('b', b) # b 1
a, b = b, a+b
print('Depois:')
print('a', a) # a 1
print('b', b) # b 1
See working on Repl.it | Ideone
In separate lines:
a = 0
b = 1
print('Antes:')
print('a', a) # a 0
print('b', b) # b 1
a = b
b = a+b
print('Depois:')
print('a', a) # a 1
print('b', b) # b 2
See working on Repl.it | Ideone
What really happens is the construction and deconstruction of tuples. Analyzing only the line a, b = b, a + b
, the interpreter will first build a tuple internally with the current values of b
and a + b
; would be the equivalent of doing temp = (b, a+b)
. Then he will deconstruct this tuple by assigning the values to (a, b)
; equivalent to (a, b) = temp
. That is, first the tuple is built with the current values, then the assignment is made, so it works as expected.
Using the function dis.dis
we can see what really happens in this instruction:
>>> print(dis.dis('a, b = b, a+b'))
1 0 LOAD_NAME 0 (b)
2 LOAD_NAME 1 (a)
4 LOAD_NAME 0 (b)
6 BINARY_ADD
8 ROT_TWO
10 STORE_NAME 1 (a)
12 STORE_NAME 0 (b)
14 LOAD_CONST 0 (None)
16 RETURN_VALUE
None
Basically:
LOAD_NAME
: Press the value from the name in the stack b
(Stack: b
);
LOAD_NAME
: Press the value from the name in the stack a
(Stack: b, a
);
LOAD_NAME
: Press the value from the name in the stack b
(Stack: b, a, b
);
BINARY_ADD
: Runs the sum of the last two values on the stack and loads the result on the stack (Stack: b, a+b
);
ROT_TWO
: Inverts the positions of the last two values in the stack (Stack: a+b, b
);
STORE_NAME
: Removes a value (b
) of the stack and stores in the name a
(Stack: a+b
);
STORE_NAME
: Removes a value (a+b
) of the stack and stores in the name b
(Stack: empty);
Which shows how it is stored before the values of b
and a+b
and only then is the assignment made.