Finding the nth Fibonacci number with Python dictionary for memoization

Question:

I am trying to understand memoization, and this fib function seems to give me the correct answers. My question is how and where the dictionary is stored. Why does it give me fib(7) and fib(8) immediately? What is the namespace of d? Is it treated like a global variable or sort of something? My codes and what the codes gave me are here. Thank you.

def fib(n, d = {}):
    if n in d:
        return d[n]
    elif n < 3:
        return 1
    else:
        d[n] = fib(n - 1, d) + fib(n - 2, d)
        print(f"n: {n}")
        print(f"d: {d}")
        return d[n]

print("fib(6):", fib(6))
print("fib(7):", fib(7))
print("fib(8):", fib(8))

--------------------------------------------------------------------------------------------

n: 3
d: {3: 2}
n: 4
d: {3: 2, 4: 3}
n: 5
d: {3: 2, 4: 3, 5: 5}
n: 6
d: {3: 2, 4: 3, 5: 5, 6: 8}
fib(6): 8
n: 7
d: {3: 2, 4: 3, 5: 5, 6: 8, 7: 13}
fib(7): 13
n: 8
d: {3: 2, 4: 3, 5: 5, 6: 8, 7: 13, 8: 21}
fib(8): 21
Asked By: nbbg

||

Answers:

Python doesn’t create a new object for the default argument for each function call. It only creates it once, when the function is defined. All subsequent calls use that same object.

If the object is immutable this obviously doesn’t matter but when you are using a dictionary, list or some other mutable objects it’s something you should be aware of.

In some ways it behaves similarly to a global variable, however if you try to access it in the global namespace or outside of the scope of the function body it will throw an exception.

To demonstrate

>>> def something(arg=[]):
...     arg.append(1)
...     return arg
...
>>> something()
[1]
>>> something()
[1, 1]
>>> something()
[1, 1, 1]
>>> arg
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 'arg' is not defined

So in your example, when you call fib(8), after previously calling fib(7) your code only has to call itself recursively once before finding the answer for fib(7) and returning it instead of having to work it’s way down to the base case of n < 3. However it will have to recurse to the base case if fib(8) is the first call you make to the function.

Answered By: Alexander
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.