four-eyes
four-eyes

Reputation: 12449

Difference between writing something on one line and on several lines

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 the two functions below should return the same.

def fibi(n):
    a, b = 0, 1
    for i in range(n):
        a, b = b, a + b
    return a

print(fibi(6))
> 8 # expected result (Fibonacci)

But

def fibi(n):
    a, b = 0, 1
    for i in range(n):
        a = b
        b = a + b 
    return a


print(fibi(6))
> 32 

Upvotes: 5

Views: 849

Answers (6)

Roque Possamai
Roque Possamai

Reputation: 41

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.

Upvotes: 0

VPfB
VPfB

Reputation: 17352

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

Upvotes: 0

glglgl
glglgl

Reputation: 91139

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)

Upvotes: 2

user559633
user559633

Reputation:

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

Upvotes: 1

Daniel Roseman
Daniel Roseman

Reputation: 599956

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

Upvotes: 13

NendoTaka
NendoTaka

Reputation: 1224

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

Upvotes: 0

Related Questions