0

I've found a Python code of Fibonacci Generator, but don't understand all of it. Can some one explain a, b = b, a + b line in particulat?

a = int(input('Give amount: '))

def fib(n):
    a, b = 0, 1
    for _ in range(n):
        yield a
        a, b = b, a + b

print(list(fib(a))

How does it work?

iz_
  • 15,923
  • 3
  • 25
  • 40
DuckGame
  • 1
  • 2

1 Answers1

1

This line of code works by creating a tuple, and then destructuring it to assign two variables at once. The result is that both a and b on the left-hand-side are assigned the results of expressions on the right-hand-side which are calculated using the original values of a and b.

The expression on the right-hand-side is b, a + b which is equivalent to (b, a + b), i.e. it creates a tuple with two components.

The assignment target on the left-hand-side is a, b which is equivalent to (a, b), i.e. it assigns to two variables simultaneously, using the values of the two components from the tuple respectively. This is called a destructuring assignment.

This is convenient because if the two assignments were written separately, as in the code below, then it would not have the desired effect. The first line changes a's value, and then the new value would (incorrectly) be used to calculate b:

# WRONG!
a = b
b = a + b
kaya3
  • 47,440
  • 4
  • 68
  • 97
  • 1
    implementation detail: no tuple is actually created in this case, rather, a specialized op code ROT_TWO is used to swap the top two elements in the interpreter stack. – juanpa.arrivillaga Nov 19 '19 at 21:55
  • BUT of course, semantically it is equivalent to creating a tuple and then using destructing assignment on that tuple. And indeed, that's what happens when the tuple display is greater than 3 elements, IIRC – juanpa.arrivillaga Nov 19 '19 at 22:00
  • Interesting and useful to know. Seems like the ROT_TWO shouldn't be necessary for this case because you could just push `b`, then push `a + b`, pop to `b` then pop to `a` (i.e. assign in opposite order). In the general case that wouldn't be equivalent for e.g. `lst[0], lst[0] = x, y`, but for assigning to simple variables this optimisation should be possible for arbitrarily many terms. – kaya3 Nov 19 '19 at 22:03