In the first version, when you write
a, b = b, a + b
the expression
b, a + b
is evaluated first. After it has been evaluated, it is subsequently assigned to a, b
with tuple unpacking. The key point is that the entire right hand side of an assignment statement is evaluated in its entirety before performing the binding of the left-hand side names.
In the second version,
a = b
# a is now re-bound and potentially has changed value
is performed first, and then
b = a + b
# the expression a + b uses the modified value of a
happens after. By which point, a
has been re-bound.
So, to illustrate with some values. The first time round the loop, after a, b = 0, 1
we have
# a == 0
# b == 1
a, b = b, a + b
Now, b, a + b
is 1, 1
. And so we have
a, b = 1, 1
But the alternative goes like this:
a = b
# same as a = 1
b = a + b
# same as b = 1 + 1
You ask in a comment:
How would Example 1 be rewritten into 2 statements?
The safest way is to introduce temporary variables. Like this:
a1 = b
b1 = a + b
# now we can assign to a and b
a = a1
b = b1
In this case you don't actually need two temporary variables, one will suffice, but this is the most general form.
This tuple unpacking is how you swap two values idiomatically in Python. In other languages you write:
temp = a
a = b
b = temp
In Python you write:
a, b = b, a