Python Fibonacci Generator, explain syntax [duplicate] - python

This question already has answers here:
Python - fibonacci numbers [duplicate]
(4 answers)
How does swapping of members in tuples (a,b)=(b,a) work internally?
(1 answer)
Closed 3 years ago.
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?

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

Related

Getting two largest numbers from three numbers without using conditional statement or loop in python 3.5

Complete the function1() function which is passed three whole
numbers.The function returns the total of the two bigger numbers.
print()
print(1, function1(1, 2, 3))
print(2, function1(11, 12, 3))
print(3, function1(6, 2, 5))
output should be
1 5
2 23
3 11
This was the question. I try googling but all I have found was using conditional
statement or loop. I was wondering if there is other way to do this without using both? Reason being is that this question was on before the introduction of conditional statement and loop. I can advance my self-studying and do it however
there must be a reason why it poped up before we go onto the next chapter.
What do you reckon?.. (During self-studying for CS101) `
you could sort the tuple of the numbers and add the first 2 values:
def function1(a, b, c):
s = sorted((a, b, c), reverse=True)
return s[0] + s[1]
sorted starts with the smalles item normally that's why you need to set reverse=True.
or you could sum the three and subtract the minimal value:
def function1(a, b, c):
return sum((a, b, c)) - min(a, b, c)

Shorthand code and Fibonnaci Sequence [duplicate]

This question already has answers here:
Multiple assignment and evaluation order in Python
(11 answers)
Closed 7 years ago.
I have found example for Fibonacci sequence that goes like this:
def fib(n):
a, b = 0, 1
while b < n:
print (b)
a, b = b, a+b
fib(20)
So here's what I don't get it:
a, b = 0, 1 # is just a shortcut for writing
a = 0
b = 1
right?
Now, following the same logic
a, b = b, a+b #should be the same as writing
a = b
b = a+b
But it isn't because if I write it like that, the output is different.
I'm having some hard time understanding why. Any thoughts?
Yes It isn't exactly the same , because when you write -
a, b = b, a+b
The value of a and b at the time of executing the statement is considered, lets say before this statement, a=1 , b=2 , then first right hand side is calculated , so b=2 is calculated and a+b=3 is calculated. Then the assignment occurs, that is a is assigned value 2 and b is assigned value 3.
But when you write -
a = b
b = a+b
The assignment occurs along with calculation, that is first b=2 is calculated, then assigned to a , so a becomes 2 , then a+b is calculated (with the changed value of a) , so a+b=4 and it is assigned to b , so b becomes 4 , and hence the difference.
a,b = b, a
This is a shorthand for swapping values of a and b , please note that if you want to swap the values without using this notation, you would need a temporary variable.
Internally how it works is that the right hand sid is made into a tuple, and then the values are unpacked, a simple test to see this is -
>>> a = 5
>>> b = 10
>>> t = a, b
>>> t
(5, 10)
>>> b, a = t
a, b = c, d is not shorthand for the following:
a = c
b = d
It's actually shorthand for this:
a, b = (c, d)
I.e., you're creating a tuple (c, d), a tuple with the values of c and d, which is then unpacked into the target list a, b. The tuple with its values is created before the values are unpacked into the target list. It actually is one atomic* operation, not a shorthand for several operations. So it does not matter whether one of the variables in the target list also occurs on the right hand side of the assignment operation.
* Not "atomic" in the sense of database ACID, but still not separate statements.
It is not the same thing.
x, y = y, x
equals to:
t = x
x = y
y = t
It actually uses a temporary variable to swap x and y.
So back to a, b = b, a+b. This expression equals to:
m = a; n = b
a = n
b = m + n

Fibonacci being very strange in Python [duplicate]

This question already has answers here:
Python - fibonacci numbers [duplicate]
(4 answers)
Closed 8 years ago.
Basically I'm quite new to Python, but ive written a code for the Fibonacci Sequence and it doesn't work, i've compared it online and its pretty much the same but when i write it slightly differently, it works! - But I have no idea why, can anyone shed some light on why it is behaving this way?
This code has been built and tested in the Python 3.3.2 Shell.
Working Code:
def fib(n):
a, b = 0, 1
while b < n:
print(b)
a, b = b, b + a
Non-Working Code:
def fib(n):
a = 0
b = 1
while b < n:
print(b)
a = b
b = b + a
I'm completely confused as to why it only works when the variables are grouped together and not when they are separate.
I believe it's in the line a,b = b,b+a.
The actual executed version does things a bit differently. An expanded form would be:
c = a
a = b
b = b + c
As b is incremented by the initial value of a, not the adjusted value.
To expand on Yeraze's answer, the actual assignment is closer to
# Make the tuple
a_b = (b, b+a)
# Unpack the tuple
a = a_b[0]
b = a_b[1]
so it's more obvious why the values are set and then assigned.

Understanding multiple assignments in Python [duplicate]

This question already has answers here:
Multiple assignment and evaluation order in Python
(11 answers)
Closed 9 years ago.
What is the difference between this:
a, b = b, a+b
And this:
a = b
b = a+b
I'm trying to follow along in the examples in the documentation and the first form (multiple assignment syntax) seems complicated to me. I tried to simplify it with the second example but it's not giving the same results. I'm clearly interpreting the first statement wrong. What am I missing?
Multiple assignment evaluates the values of everything on the right hand side before changing any of the values of the left hand side.
In other words, the difference is this:
a = 1
b = 2
a = b # a = 2
b = a + b # b = 2 + 2
vs. this:
a = 1
b = 2
a, b = b, a + b # a, b = 2, 1 + 2
Another way of thinking about it is that it's the equivalent of constructing a tuple and then deconstructing it again (which is actually exactly what's going on, except without an explicit intermediate tuple):
a = 1
b = 2
_tuple = (b, a+b)
a = _tuple[0]
b = _tuple[1]

Looping a variable-length number of variables [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Get the cartesian product of a series of lists in Python
Suppose I have an array of length n, representing n variables, and a function f of n variables. I want to sum over f applied to all values of the n variables in some finite set (i.e. {0,1}). Conceptually, it would be something like
for x[1] in {0,1}:
for x[2] in {0,1}:
...
sum += f(x[1], ..., x[n])
but obviously you can't write this.
Is there a nice way to do it, say in Python? (For the particular case of values in {0,1}, I could just loop over binary representations of integers from 0 to 2^n-1, but I want a more general solution).
# f is a function
# K is a list of possible values your variable may take
# n is number of args that f takes
import itertools
def sum_of_f_over_K_n(f,K,n):
K_to_the_n = [K for i in xrange(n)]
return sum(map(lambda(x):f(*x),itertools.product(*K_to_the_n)))
some_list = [0,1] # where your variables come from
def sample_func(a,b,c,d,e):
return a or b or c or d or e
sum_of_f_over_K_n(sample_func, some_list, 5) == 2**5 -1

Categories