Nth Fibonacci in python

Question:

def fibonaci(i,memo):
    if i == 0 or i == 1:
       return i

    if memo[i]==-1:
       memo[i] = fibonaci(i-1,memo) + fibonaci(i-2,memo)

    return memo[i]

def fibo(n):
    a = []
    return fibonaci(n,a)

print(fibo(2))

I’m a Java programmer learning python. This algorithm computes the nth fibonacci number using recursion + memoization. I don’t understand why I’m seeing this error "IndexError: list index out of range" when running the program in python. Can anybody help? Thanks a ton!

Asked By: noob_coder

||

Answers:

I made few changes in your code to get nth Fibonacci no.(there might be other way too)

def fibonaci(i,memo):
    if i == 0 or i == 1:
       return i

    if memo[i] == -1:
       memo[i] = fibonaci(i-1,memo) + fibonaci(i-2,memo)

    return memo[i]

def fibo(n):
    a = [-1] * n
    return fibonaci(n-1,a)

print(fibo(5))
print(fibo(10))
print(fibo(13))
print(fibo(57))

And output is :-

3
34
144
225851433717
Answered By: aberry

As suggested in the comments to your question, there is no way memo[i]==-1 could be true.

I understand your want to test something like "if the value for fibonacci(i) has not yet been memoized", but the way Python will tell you in index is not present is certainly not by returning some magic value (like -1), but instead by raising an exception.

Looking up "EAFP" (easier to ask for forgiveness than permission) on your favorite search engine might show you why exceptions are not to be understood as errors, in python.

In addition, memoization will be preferably implemented by a dictionary, rather than a list (because dictionaries allow to map a value to any possible key, not necessarily to the next integer index value).

Without changing too much to the structure of your program, I would suggest the following :

def fibonaci(i,memo):
    if i == 0 or i == 1:
        return i

    try:
        memo[i]
    except KeyError:
        memo[i] = fibonaci(i-1,memo) + fibonaci(i-2,memo)

    return memo[i]

def fibo(n):
    a = {} 
    return fibonaci(n,a)

print(fibo(2))
Answered By: Patrick Aszody

You are seeing the error because you create an empty list with a = [] and then you try to look into it. You need to create a list long enough to index from zero up to n-1.

That being said, an easy way to do memoisation in Python is using the cache function from functools. This code does the memoisation for you:

from functools import cache


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


for n in range(10):
    print(f"{fib(n) = }")

It isn’t quite as efficient in running time, but in programmer time it is.

Answered By: Thomas Mailund
Categories: questions Tags: ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.