10

I'm just trying to improve my programming skill by making some basic functions.

I want to fill a list with fibonacci values, but I think my code gives the sum of all the numbers put together and prints that instead..

numberlist = []
i = 0
for i in range(20):
    numberlist.append(i)

print numberlist

fibonaccinumbers = []

for n in numberlist:
    def fib(n):
        a, b = 0, 1
        for i in range(n):
            a, b = b, a + b
        return a
    a = fib(n)
    fibonaccinumbers.append(a)


print a

Where have I gone wrong?

9
  • 5
    +1 Any question that begins with "I've been trying to improve my skills" deserves an upvote and immediate attention Commented Mar 8, 2013 at 23:57
  • But its true, I was just writing this to be more competent at programming.. Commented Mar 9, 2013 at 0:03
  • 4
    @georgesl: a, b = b, a + b is perfectly fine in Python. Commented Mar 9, 2013 at 0:07
  • 2
    @georgesl and once you get used to it you will wonder why other languages can't handle something so clean as multiple return values Commented Mar 9, 2013 at 0:08
  • 1
    @DaBx I was being perfectly honest! Improving is the noblest goal of a programmer Commented Mar 9, 2013 at 0:10

12 Answers 12

12
print a

Well, you print the final value.


Also some more comments on your code:

numberlist = []
i = 0
for i in range(20):
    numberlist.append(i)

You don’t need to initialize i there, the for loop does that for you. Also, you can simplify the whole block by just doing this:

numberlist = list(range(20))

And given that you don’t actually need that to be a list, you don’t need to construct that at all but you can just run for n in range(20) later.

Then you are redefinining your fib function inside the loop over and over again. You should define it outside of it and just reuse it.

Also, when you know you want to create a list of multiple fibonacci numbers, it helps to just store all the numbers you calculate in between. That way you don’t have to do the same things over and over again. You can also use a generator function to make that all easier:

def fibGenerator():
    a, b = 0, 1
    yield 0
    while True:
        a, b = b, a + b
        yield a

fibonaccinumbers = []
fib = fibGenerator()
for n in range(20):
    fibonaccinumbers.append(next(fib))

Instead of iterating over a range and calling next on the generator manually, you then can also just use the take-recipe from itertools to do it just like this:

fibonaccinumbers = take(20, fibGenerator())

On generators

Still not too sure what the generator does however.

A generator is a Python function which generates a sequence of return values. The values are generated lazily, that means when you request it. You create a generator by simply using yield instead of return. A yield will “return” a value and pause the generator. The next time you request a value, the generator will continue where it left off.

Using a generator allows you to create an endless sequence. As you see in the definition of fibGenerator above, there is a endless while-loop which has a yield inside. As the generator stops, it won’t hang up despite that loop.

Here is a quick self-explanationary example:

>>> def example():
    print('begin')
    i = 0
    while True:
        print('Calculating next value')
        yield i
        i += 1

>>> g = example()
>>> next(g)
begin
Calculating next value
0
>>> next(g)
Calculating next value
1
>>> next(g)
Calculating next value
2
>>> next(g)
Calculating next value
3
>>> next(g)
Calculating next value
4

The next function is the built-in function that requests the next value from the iterable. An iterable is anything you can iterate (e.g. for x in iterable: ...); and any generator is also an iterable.

Sign up to request clarification or add additional context in comments.

2 Comments

@uʍopǝpısdn Hah, first! :P ^^
Best explanation of the yield statement I've seen. It fit right in with my experiments on Fibonacci numbers. Thank you!
2

Sorry I'm being an idiot. I was printing 'a' which is the last iterated calculation of fibonacci..

I should have been printing my list instead.

Damn...

1 Comment

It's still good you posted though. Suggestions: 1) Pull your function definition outside of the loop. 2) Range returns a list, so you can just say for n in range(20) instead of for n in numberlist and doing all that work in the beginning. 3) I recommend looking into list comprehensions, the second loop could look something like: fibonaccinumbers = [fib(n) for n in range(20)]
2

The problem is on the last line. A distraction, I'm sure: you should be printing the list, not a.

Some other tips:

1: This whole block is just recreating the list returned by range:

numberlist = []
i = 0
for i in range(20):
    numberlist.append(i)

Assigning i = 0 is also moot. Instead, try:

numberlist = range(20)

In python 3, call list(range(20)), since range doesn't create a full-fledged list.

2: redefining the fib function on every pass of the loop won't create problems, but is surely not necessary. Move the definition outside :)

1 Comment

Whoops sorry guys, only just saw the last comments! I'll get right on it.
2

Thought I would share some pyLove:

def fib(n, a = 0, b = 1):
    seq = [a,b]
    while len(seq) < n:
        seq += [seq[len(seq)-1] + seq[len(seq)-2]]
    return seq

print(fib(13))

output is:

[0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144]

or:

#or if you want to make up your own
print(fib(13, 1597, 2584))

output is:

[1597, 2584, 4181, 6765, 10946, 17711, 28657, 46368, 75025, 121393, 196418, 317811, 514229]

Comments

1

In the spirit of improving programming skills: you could use a generator and itertools.islice() to get the list of the first n fibonacci numbers:

from itertools import islice

def fib(a=0, b=1):
    yield a
    while True:
        yield b
        a, b = b, a + b

fibonacci_numbers = list(islice(fib(), 20))
print(fibonacci_numbers)

Output

[0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, 377, 610, 987, 1597, 2584, 4181]

Comments

1

I condensed it and took on board the fact that 'range' or at least list(range()) creates its own list:

numberlist = list(range(20))

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

fibonaccinumbers = [fib(n) for n in numberlist]

print fibonaccinumbers

It seems to work, printing every fibonacci value up to the 20th iteration. How is it that I can call 'fib(n)' outside of the def without doing some weirdness such as:

a = fib(n)

That was the style I was used to before. In any case, does the program look good now?

4 Comments

If you change it as @J.F. Sebastian recommends, it will run much faster. (Because it only runs through the loop in fib once.)
Gotcha, I'll see if I can do that.
You might want to look at all the answers… Also please do not answer your own question just to add further questions but edit your question instead. See also the FAQ.
Ok sorry, thank you for all your help though. Still not too sure what the generator does however. I read the tip (stackoverflow.com/questions/102535/…)
1

nth term in fibonacci series is:

enter image description here where enter image description here and enter image description here

Using the above identity in, the series can be generated using list comprehension:

[int(((((1 + math.sqrt(5)) / 2) ** x) - (((1 - math.sqrt(5)) / 2) ** (x))) / math.sqrt(5)) for x in range(n)] //where n is the number of terms in the series

Comments

0

Since each fibonacci number is generated from all prior ones, it doesn't make sense to calculate each one from scratch. It is better to use the list you are collecting Fibonacci numbers in to calculate each subsequent one:

def FibList(n):
    rc = []
    for i in xrange(n):
        if i < 2:
            rc.append(1)
        else:
            rc.append(rc[i-2] + rc[i-1])

    return rc

print FibList(20)

If you really want to be spiffy, you can create a generator function that calculates a Fibonacci value, and use that to build your list:

def Fib(n):
    n1 = 1
    n2 = 1

    for i in xrange(n):
        if i < 2:
            yield 1
        else:
            n3 = n1 + n2
            n1 = n2
            n2 = n3
            yield n3

fiblist = [x for x in Fib(20)]
print fiblist

In a generator function, the 'yield' keyword returns each value of the list. The line where fiblist uses something called a "list comprehension` to build a list using a generator. You could also use your generator in a for loop:

for fnum in Fib(20):
    print fnum

Comments

0

I just used the formula and plugged in values:

import math 

def Fibs(n):

 for i in range (n):

     Fn=int(((((1+math.sqrt(5))**i) - ((1-math.sqrt(5)) **i))/(2**i) * (math.sqrt(5)))/5)
     print (Fn)

Fibs(int(input())

Comments

0

Why not use a list comprehension? Here is how I would solve the problem. I would define a function to calculate the n th ter om of the fibonacci sequence as follows.

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

Then I would use list comprehension to get the sequence that I want.

fib_sequence = [fibo(i) for i in range(n+1)]

Comments

0

If you want a really simple way to print a certain number of items in the fibonacci sequence you can do this:

num = input("How many numbers of the fibonacci sequence would you like to print?\n\n")
numbers = int(num)

a = 0
b = 1
print(a)
print(b)
for i in range(numbers):
    c = a + b
    print(c)
    a = b
    b = c

Since the rule of the fibonacci sequence is to have each item be the sum of the previous two items, you can create two variables, add them then set the value of the variables a and b to the new values of b and c and continue the loop.

If you want to contain these items in a list you can write this instead:

num = input("How many numbers of the fibonacci sequence would you like to print?\n\n")
numbers = int(num)

fib = [1, 1, 2, 3, 5]

for i in range(numbers-5):
    fib.append(fib[-1] + fib [-2])

for i in range(numbers):
    print(fib[i])

You can also just print the whole list at once by typing print(fib) instead of using the for loop to print the items on sepeate lines.

Comments

0
def fibonacci(number):
  numbers = [0, 1]
  while len(numbers) < number:
    numbers[len(numbers):len(numbers)] = [numbers[len(numbers) - 2] + numbers[len(numbers) - 1]]
  return numbers

The two last values in the list gets added up every time the loop runs. A new position in the list is created with the every new fibonacci value while iterating to the length of input.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.