I am solving a problem in three different ways, two are recursive and I memoize them myself. The other is not recursive but uses math.factorial. I need to know if I need to add explicit memoization to it.
Thanks.
I am solving a problem in three different ways, two are recursive and I memoize them myself. The other is not recursive but uses math.factorial. I need to know if I need to add explicit memoization to it.
Thanks.
Python's math.factorial is not memoized, it is a simple for loop multiplying the values from 1 to your arg. If you need memoization, you need to do it explicitly.
Here is a simple way to memoize using dictionary setdefault method.
Python's math.factorial is not memoized.
I'm going to guide you through some trial and error examples to see why to get a really memoized and working factorial function you have to redefine it ex-novo taking into account a couple of things.
The other answer actually is not correct. Here,
the line
computes both
x
andmath.factorial(x)
every time and therefore you gain no performance improvement.You may think of doing something like this:
but actually this is wrong as well. Yes, you avoid computing again the factorial of a same
x
but think, for example, if you are going to calculatemyfact(1000)
and soon after thatmyfact(999)
. Both of them gets calculated completely thus not taking any advantage from the fact thatmyfact(1000)
automatically computesmyfact(999)
.It comes natural then to write something like this:
This is going to work. Unfortunately it soon reaches the maximum recursion depth.
So how to implement it?
Here is an example of truly memoized factorial, that takes advantage of how factorials work and does not consumes all the stack with recursive calls:
I hope you find this useful.
EDIT:
Just as a note, a way to achieve this same optimization having at the same time the conciseness and elegance of recursion would be to redefine the function as a tail-recursive function.
Tail recursion functions in fact can be recognized by the interpreter/compiler and be automagically translated/optimized to an iterative version, but not all interpreters/compilers support this.
Unfortunately python does not support tail recursion optimization, so you still get:
when the input of my_fact is high.
I'm late to the party, yet here are my 2c on implementing an efficient memoized factorial function in Python. This approach is more efficient since it relies on an array-like structure (that is
list
) rather than a hashed container (that isdict
). No recursion involved (spares you some Python function-call overhead) and no slow for-loops involved. And it is (arguably) functionally-pure as there are no outer side-effects involved (that is it doesn't modify a global variable). It caches all intermediate factorials, hence if you've already calculatedfactorial(n)
, it will take you O(1) to calculatefactorial(m)
for any 0 <= m <= n and O(m-n) for any m > n.Search for math_factorial on this link and you will find its implementation in python:
http://svn.python.org/view/python/trunk/Modules/mathmodule.c?view=markup
P.S. This is for python2.6