Where is the difference when I write something on one line, seperated by a ,
and on two lines. Apparently I do not understand the difference, because I though t
Your difference comes in on the lines:
1)
>>> a, b = 0, 1
>>> a, b = b, a+b
>>> a
1
>>> b
1
vs:
2)
>>> a, b = 0, 1
>>> a = b
>>> b = a+b
>>> a
1
>>> b
2
in the first case, a = 1
and b = 0 + 1
before the variable's values have changed. You're basically saying "with (a,b)
at given state X, set (a,b)
to values (0,1)
."
A good way to see the difference in these sort of things is to use the disassembly module (follow link to see meaning of codes):
>>> from dis import dis
>>> a, b = 0, 1
>>> dis('a, b = b, a+b')
1 0 LOAD_NAME 0 (b)
3 LOAD_NAME 1 (a)
6 LOAD_NAME 0 (b)
9 BINARY_ADD
10 ROT_TWO
11 STORE_NAME 1 (a)
14 STORE_NAME 0 (b)
17 LOAD_CONST 0 (None)
20 RETURN_VALUE
>>> a, b = 0, 1
>>> dis('a = b; b = a+b')
1 0 LOAD_NAME 0 (b)
3 STORE_NAME 1 (a)
6 LOAD_NAME 1 (a)
9 LOAD_NAME 0 (b)
12 BINARY_ADD
13 STORE_NAME 0 (b)
16 LOAD_CONST 0 (None)
19 RETURN_VALUE
At the first case, the commands
a, b = b, a + b;
will do first the sum a + b
and then will do the assignment. In that case, b always contains 1. This explains why the final result is 6, because you are adding 1 six times.
The second code you posted its correct.
The difference is because in the second example you set a
to b
before referencing a
. Your values on the second example will be off. Here is an example:
a = 5
b = 6
ex.1:
a, b = b, a+b // a = 6 and b = 11
ex.2:
a = b // a = 6
b = a + b // b = 6+6 or 12
The first example is correct
To find a replacement for
a, b = b, a + b
you must become aware that this assignment is performed "step by step".
So its equivalent is
old_a = a
a = b
b = old_a + b # note the old_a here, as a has been replaced in the meanwhile.
Demo:
def fibi(n):
a, b = 0, 1
for i in range(n):
a, b = b, a + b
return a
def fibi2(n):
a, b = 0, 1
for i in range(n):
old_a = a
a = b
b = old_a + b
return a
>>> fibi(0)
0
>>> fibi(1)
1
>>> fibi(2)
1
>>> fibi(3)
2
>>> fibi(4)
3
>>> fibi(5)
5
>>> fibi(6)
8
>>> fibi(7)
13
>>>
>>>
>>>
>>> fibi2(0)
0
>>> fibi2(1)
1
>>> fibi2(2)
1
>>> fibi2(3)
2
>>> fibi2(4)
3
>>> fibi2(5)
5
>>> fibi2(6)
8
>>> fibi2(7)
A perfect explanation from Raymond Hettinger can be found in this PyCon 2013 video between 33:13 and 38:17:
https://www.youtube.com/watch?v=OSGv2VnC0go
Quote from his presentation:
- don't underestimate the advantages of updating state variabes at the same time
- eliminates an entire class of errors due to out-of-order updates
This is because of Python's tuple unpacking. In the first one, Python collects the values on the right, makes them a tuple, then assigns the values of the tuple individually to the names on the left. So, if a == 1 and b == 2:
a, b = b, a + b
=> a, b = (2, 3)
=> a = 2, b = 3
But in the second example, it's normal assignment:
a = b
=> a = 2
b = a + b
=> b = 4