35

I need to make a program that asks for the amount of Fibonacci numbers printed and then prints them like 0, 1, 1, 2... but I can't get it to work. My code looks the following:

a = int(raw_input('Give amount: ')) def fib(): a, b = 0, 1 while True: yield a a, b = b, a + b a = fib() a.next() 0 for i in range(a): print a.next(), 

;

3
  • 1
    I think 'while True' is more concise Commented Jul 4, 2016 at 8:57
  • How could the 2nd iteration understand "a=1"? Shouldn't we have to write a = a+b rather than "a, b=b, a+b" Commented Aug 27, 2017 at 20:38
  • 1
    @user177196 That expression is a two-part expression. First, it makes a tuple with (b,a+b) using the current values of a and b, then it unpacks that tuple when assigning it to a,b. (Technically speaking Python can do some optimization, but I'm ignoring this for now). Commented Jan 12, 2019 at 20:24

23 Answers 23

54

I would use this method:

Python 2

a = int(raw_input('Give amount: ')) def fib(n): a, b = 0, 1 for _ in xrange(n): yield a a, b = b, a + b print list(fib(a)) 

Python 3

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))) 
Sign up to request clarification or add additional context in comments.

4 Comments

fib(0) doesn't yield anything, which can be fixed using range(n+1) instead.
I rewrote this by using a=0, b=1, a=b and b=a+b because I was uncomfortable with that notation but it gave completely different answers. Am I missing something?
As The Amateur Coder says below, should be yield b not yield a. So it begins 1,1,2,3, etc... No?
@Neosapien When you do a = b separately, then the result of b = a + b is affected. i.e it is now adding the "new" a to b. When you do multiple assignment on one line, first the right hand side is being evaluated (i.e "old" a added to b) and only then the assignment is done. See Multiple assignment and evaluation order in Python for more details
27

You are giving a too many meanings:

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

vs.

a = fib() 

You won't run into the problem (as often) if you give your variables more descriptive names (3 different uses of the name a in 10 lines of code!):

amount = int(raw_input('Give amount: ')) 

and change range(a) to range(amount).

Comments

17

Since you are writing a generator, why not use two yields, to save doing the extra shuffle?

import itertools as it num_iterations = int(raw_input('How many? ')) def fib(): a,b = 0,1 while True: yield a b = a+b yield b a = a+b for x in it.islice(fib(), num_iterations): print x 

.....

Comments

14

Really simple with generator:

def fin(n): a, b = 0, 1 for i in range(n): yield a a, b = b, a + b ln = int(input('How long? ')) print(list(fin(ln))) # [0, 1, 1, 2, 3, 5, 8, 13, 21, 34, ...] 

1 Comment

So this is how yield works! BTW, it should be yield b instead of yield a as it repeats the elements twice (a becomes b).
5

Python is a dynamically typed language. the type of a variable is determined at runtime and it can vary as the execution is in progress. Here at first, you have declared a to hold an integer type and later you have assigned a function to it and so its type now became a function.

you are trying to apply 'a' as an argument to range() function which expects an int arg but you have in effect provided a function variable as argument.

the corrected code should be

 a = int(raw_input('Give amount: ')) def fib(): a, b = 0, 1 while 1: yield a a, b = b, a + b b = fib() b.next() for i in range(a): print b.next(), 

this will work

2 Comments

I am gettting error on this File "D:\Projects\Python\fibonacci.py", line 18, in <module> b.next() AttributeError: 'generator' object has no attribute 'next'
I found it for Python 3, it is b.__next__(). Sorry :) and Thanks
4
def fibonacci(n): fn = [0, 1,] for i in range(2, n): fn.append(fn[i-1] + fn[i-2]) return fn 

Comments

3

To get the fibonacci numbers till any number (100 in this case) with generator, you can do this.

def getFibonacci(): a, b = 0, 1 while True: yield b b = a + b a = b - a for num in getFibonacci(): if num > 100: break print(num) 

Comments

3
def genFibanocciSeries(): a=0 b=1 for x in range(1,10): yield a a,b = b, a+b for fib_series in genFibanocciSeries(): print(fib_series) 

Comments

2

Your a is a global name so-to-say.

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

Whenever Python sees an a, it thinks you are talking about the above one. Calling it something else (elsewhere or here) should help.

Comments

2

Also you can use enumerate infinite generator:

for i,f in enumerate(fib()): print i, f if i>=n: break 

Comments

2

Also you can try the closed form solution (no guarantees for very large values of n due to rounding/overflow errors):

 root5 = pow(5, 0.5) ratio = (1 + root5)/2 def fib(n): return int((pow(ratio, n) - pow(1 - ratio, n))/root5) 

Comments

2

You had the right idea and a very elegant solution, all you need to do fix is your swapping and adding statement of a and b. Your yield statement should go after your swap as well

a, b = b, a + b #### should be a,b = a+b,a #####

`###yield a` 

Comments

2

Simple way to print Fibonacci series till n number

def Fib(n): i=a=0 b=1 while i<n: print (a) i=i+1 c=a+b a=b b=c Fib(input("Please Enter the number to get fibonacci series of the Number : ")) 

Comments

2
a = 3 #raw_input def fib_gen(): a, b = 0, 1 while 1: yield a a, b = b, a + b fs = fib_gen() next(fs) for i in range(a): print (next(fs)) 

1 Comment

only code answers are discouraged here. It is encouraged to add some details to how this code will fix the problem.
2

I recently discovered this type of construct (many thanks to @KellyBundy for this), so I couldn't resist:

n = 20 fib = (a for a,b in [(0,1)] for _ in range(n) for a,b in [(b,a+b)]) print(list(fib)) # [1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, 377, 610, 987, 1597, 2584, 4181, 6765] 

Comments

1

I've build this a while ago:

a = int(raw_input('Give amount: ')) fab = [0, 1, 1] def fab_gen(): while True: fab.append(fab[-1] + fab[-2]) yield fab[-4] fg = fab_gen() for i in range(a): print(fg.next()) 

No that fab will grow over time, so it isn't a perfect solution.

Comments

1

It looks like you are using the a twice. Try changing that to a different variable name.

The following seems to be working great for me.

def fib(): a, b = 0, 1 while True: yield a a, b = b, a+b f = fib() for x in range(100): print(f.next()) 

Comments

1

i like this version:

array = [0,1] for i in range(20): x = array[0]+array[1] print(x) array[0] = array[1] array[1] = x 

Comments

0

Below are two solution for fiboncci generation:

def fib_generator(num): ''' this will works as generator function and take yield into account. ''' assert num > 0 a, b = 1, 1 while num > 0: yield a a, b = b, a+b num -= 1 times = int(input('Enter the number for fib generaton: ')) fib_gen = fib_generator(times) while(times > 0): print(next(fib_gen)) times = times - 1 def fib_series(num): ''' it collects entires series and then print it. ''' assert num > 0 series = [] a, b = 1, 1 while num > 0: series.append(a) a, b = b, a+b num -= 1 print(series) times = int(input('Enter the number for fib generaton: ')) fib_series(times) 

Comments

0

Why do you go for complex here is one of my snippet to work on!!

n = int(input('Enter your number..: ')) a = 0 b = 1 c = 0 print(a) print(b) for i in range(3, n+1): c = a+b print(c) a,b=b,c 

check out my git - rohith-sreedharan

Comments

0

Write the following code:

nterm = int(input("How many Fibonacci numbers do you want to find out? ")) n1 = 0 n2 = 1 fibonacciList = [ n1, n2 ] if nterm >= 1: for i in range(nterm): fibonacciList.insert( len(fibonacciList), fibonacciList[-1] + fibonacciList[-2] ) print(fibonacciList[0:len(fibonacciList) - 2]) else: print("Invalid value") 

len means length.

;

Comments

0

I need to make a program that asks for the amount of Fibonacci numbers printed and then prints them like 0, 1, 1, 2... but I can't get it to work. My code looks the following:

Since noone answered directly to your code...

>>> def fib(): ... a,b = 0,1 ... while True: ... yield a ... # for code clarity I've spit, maybe someone is learning ... a=b ... b= a+b ... # renamed 'a' to 'gen' to not confuse with 'a' and 'b' in function. for code readability >>> gen = fib() # we assign generator to variable (so we wont re-run it >>> next(gen) # you had a.next() or gen.next() this is not a method of generator, # it is built-in in python for iterators 0 >>> next(gen) 1 >>> next(gen) 2 >>> next(gen) 4 >>> next(gen) 8 >>> next(gen) 16 

... and so on... of course you can acreate a loop if you want :)

Comments

-2

We can use it in a short way without through 'yield and 'next' statements

def fib(n): return n if n <= 1 else fib(n - 1) + fib(n - 2) 

1 Comment

Yeah but the question is asking to print the first n numbers, not the nth number...

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.