Difference between defining multiple variable at a time and individually - python

I am a newbie in Python and I'm trying to learn Python through self-learning. I was trying to build Fibonacci series using a while loop. Here is my code, which doesn't return the desired result. Could anyone explain the problem?
a = 0
b = 1
while b<100:
print(b)
a = b
b = a + b
If we define a, b simultaneously like a, b = b, a+b, this works perfectly. Why is this happening? I don't understand because in both cases I am defining a and b the same way.

This is because programming languages like Python, and many others, execute the statements you write in the order you write them.
This means that by the time you execute b = a + b, the value of a has already changed in the previous line.
An easy way to solve this would be using a third variable to store the results temporarily.
a = 0
b = 1
c = 1
while c < 100:
print(c)
c = a + b
a = b
b = c

You are making one small mistake.
When you do a = b, you are changing the value of a. After this, when you do b=a+b, it is actually equivalent to b = b+b => b=2b.
To avoid this, use a temporary variable temp and storethe value of a in it. Then change the value of a using a = b. Then do, a = a+b.
Following is the code:
a=0
b=1
while b<100:
print(b)
temp = a
a = b
b = temp+b
When you do a, b = b, a+b, the previous value of a is used for calculating the new b, we have don a similar thing above by storing the previous value of a in temp

Operator "comma" (,) in Python is used to create a tuple, and it is allowed to omit the parentheses that surround a tuple. The expression a, b = b, a+b is actually an assignment of one tuple to another:
(a, b) = (b, a + b)
This statement is executed by evaluating the tuple constructor on the right-hand side (b, a + b). At this point, a new anonymous tuple (let's call it c) is created and the original values of a and b are not needed anymore. The tuple is then assigned elementwise to the tuple on the left-hand side. The new value of a becomes c[0] (that is, former b) and the new value of b becomes c[1] (that is, former a+b).

Your code is not working because you are changing the value of a before evaluating b. In the Fibonacci series, you want the previous value of a and b. You can use list as above or can introduce another variable to store values.
while True:
temp = a + b
if temp >100:
break
print(temp)
a = b
b = temp
For reference, here is a simple implementation using list:
lst = [0, 1]
while True:
temp = lst[-1]+lst[-2]
if temp>100:
break
lst.append(temp)
print(lst)

Related

Why Python can achieve a, b = b, a [duplicate]

This question already has an answer here:
How does swapping of members in tuples (a,b)=(b,a) work internally?
(1 answer)
Closed 1 year ago.
If we need to swap variables a and b in C or Java, we need to have something (pseudo code) like:
tmp = a;
a = b;
b = tmp;
Why Python can do it by a, b = b, a. What happened with it?
Not sure whether it is the right place for this question. But I do appreciate it if someone could give me some clues.
It's because python provides a special "tuple unpacking" syntax that many other languages don't have. I'll break apart what's going on:
The b, a on the right of the equals is making a tuple (remember, a tuple is pretty much the same as a list, except you can't modify it). The a, b on the left is a different syntax that's unpacking the tuple, i.e. it takes the first item in the tuple, and store it in the first variable listed, then it takes the second item and stored it in the second variable, and so forth.
This is what it looks like broken up in multiple steps:
a = 2
b = 3
my_tuple = a, b
print(my_tuple) # (2, 3)
b, a = my_tuple
print(a) # 3
print(b) # 2
And here's another, simpler examples of tuple unpacking, just to help wrap your mind around it:
x, y, z = (1, 2, 3)
print(x) # 1
print(y) # 2
print(z) # 3
By the way, Python's not the only one, Javascript can do it too, but with arrays:
[a, b] = [b, a];

swapping using the index of an element

When I was watching videos about introduction to lists for Python I encountered this code:
b = ["banana", "apple", "Microsoft"]
print(b)
(when i print this)
'banana','apple','Microsoft'
I was told to swap the first element and the third element using their index. The working solution that they gave me was this:
b[0], b[2] = b[2], b[0]
print(b)
(when i print this):
'Microsoft','apple','banana'
which was correct. However, I don't understand how the code works, so can anyone please explain?
In most other languages, you would need to create a temporary variable and then switch them over. In Python, this would look like:
a = 1
b = 2
temp = a
a = b
b = temp
Python allows you to swap these in one line.
a = 1
b = 2
a, b = b, a
Now, b = 1 and a = 2
The [brackets] at the end of the variable references the position within the list.

python fibonacci - what is the difference? [duplicate]

This question already has answers here:
Python variable assignment question
(6 answers)
Closed 6 years ago.
I am learning python and I have some question:
What is the difference between
a,b = 0,1
for x in range(100):
print(a)
a=b
b=a+b
and
a,b = 0,1
for x in range(100):
print(a)
a,b = b, a+b
First one gives bad result, but why?
Because you first set a = b, your new b will have the value of twice the old b. You overwrite a to early. A correct implementation should use a temporary variable t:
a,b = 0,1
for x in range(100):
print(a)
t=a
a=b
b=t+b
This is basically what you do by using sequence assignment.
In your original code you have:
a,b = 0,1
for x in range(100):
print(a)
a=b # a now is the old b
b=a+b # b is now twice the old a so b'=2*b instead of b'=a+b
So this would result in jumping by multiplying with two each time (after first loading in 1 into a the first step).
An equivalent problem is the swap of variables. If you want a to take the value of b and vice versa, you cannot write:
#wrong swap
a = b
b = a
Because you lose the value of a after the first assignment. You can use a temporary t:
t = a
a = b
b = t
or use sequence assignment in Python:
a,b = b,a
where a tuple t = (b,a) is first created, and then assigned to a,b.

Understanding recursion with the help of Iteration

def unZip(master3):
c = len(master3)
sub1=''
sub2=''
for i in range(0,c,2):
sub1+=master3[i]
sub2+=master3[i+1]
print(sub1,",",sub2)
basically I have written this code that separates alternative char from string and shows them separately,
I have been trying to convert or comprehend this with recursion but I have been failing lately.
Here is my try, can someone tell me how should I approach it?
def unzip(a):
storage1=''
storage2=''
storage3=''
storage4=''
if len(a)==0:
return 0
else:
if len(a)>=1:
storage1=a[0::2]
storage2=a[1::2]
storage3+=storage1
storage4+=storage2
print(storage3,storage4)
return unzip(a[0]+a[1:])
instead of using slicing to determine your strings you should be taking one character at a time off your string and then recalling your recursive function like so
def unzip(s, a, b='', c=''):
if len(a) == 0:
return b + ', ' + c
if s%2 == 0:
b += a[0]
else:
c += a[0]
return unzip(s+1, a[1:], b, c)
print unzip(0, 'HelloWorld')
Hlool, elWrd
What that does is it starts with the string a and alternates between adding to b or c with the variable s depending on whether it is even or odd. Add the first letter of a to either b or c and then remove that letter from a. Then call the function again but with s+1. If the length of a is zero then return b and c and then print your result
To get the same results with what you have you could simplify yours down to
a = 'HelloWorld'
storage1=a[0::2]
storage2=a[1::2]
print(storage1,storage2)
('Hlool', 'elWrd')
The slicing takes care of getting every other letter in a and then you can just print that. The way you have it set up now it will just keep passing a and become an infinite loop since the size of a will never change.

Python: yield vs print in a loop

I am a beginner in Python currently working through Project Euler's problems (here for those who have not heard about it). I have solved this particular problem, however it leaves me with some questions:
def fibsum():
result = []
a, b = 0, 1
while True:
a, b = b, a + b
print b
if b < 4000000 and b % 2 == 0:
result.append(b)
if b > 4000000:
break
print sum(result)
fibsum()
When I run this using PowerShell, first it prints out all the numbers I need (although, it goes one over), and then finally prints the sum:
1
2
3
5
8
...
3524578
5702887 <-- This is over 4,000,000. Why is this here?
4613732 <-- This is the answer.
Is there any way that I can have the loop stop iterating before it reaches the first value over 4,000,000?
For the sake of saving space, is there any way that I can have all of the values print out in a list format ([ , , , ]), if I decide to use print?
When I replace print in the original code with yield or return(for the variable b), the program won't print anything out, despite there still being
print sum(result)
at the end of the function.
Is there any way that I can make this easier, without having to define result and appending values to it? When the values are returned in a format similar to the actual outcome, sum() doesn't seem to work.
1.Just move the 2nd condition before you print b:
while True:
a, b = b, a + b
if b > 4000000:
break
print b
if b < 4000000 and b % 2 == 0:
result.append(b)
2.Don't print b in loop, rather print the result once you break out.
3.Well, as for return, it's pretty clear that you return out of function, so the following code in function is not executed and hence your list is not populated.
yield is used to create a generator function, where every execution of your function returns the next value. So, you would have to call your function multiple times, thus adding the yielded value to a list defined outside. And when there is nothing to return, your function will break.
To understand yield keyword usage more clearly, take a look at this post: What does the "yield" keyword do in Python?
You can edit your code to use yield like this (haven't tested it):
def fibsum():
a, b = 0, 1
while True:
a, b = b, a + b
if b > 4000000:
break
yield b
result = []
for val in fibsum():
if val < 4000000 and val % 2 == 0:
result.append(val)
print sum(result)
So, in for loop, each call to fibsum() function generates the next value, which you add in the list, based on the condition.

Categories