Factorials
Jacek Generowicz
jacek.generowicz at cern.ch
Tue Sep 23 05:33:24 EDT 2003
bokr at oz.net (Bengt Richter) writes:
> You could also let the factorial benefit from its own experience, e.g.,
>
> >>> def factorial(n, cache={}):
> ... fn = cache.get(n)
> ... if fn: print 'got cached %s!'%n; return fn
> ... if n<2: cache[n]=1; return 1
> ... return cache.setdefault(n, n*factorial(n-1))
> ...
Or, you could let _any_ (keywordless) function benefit from its own
experience:
# General memoizer: takes a function as returns another function which
# has the same semantics as the original, but caches previously
# calculated values
def memoize(callable):
cache = {}
def proxy(*args):
try: return cache[args]
except KeyError: return cache.setdefault(args, callable(*args))
return proxy
# A quick and dirty timer utility (timeit module in 2.3 ?), just to
# help us see how we're doing.
import time
def timer(fn, *args):
start = time.time()
val = fn(*args)
stop = time.time()
print "Took", stop-start, "seconds ..."
return val
# The function we want to use
def factorial_rec(n):
if n <= 1:
return 1
else:
return n*factorial_rec(n-1)
# Now, make a cache-enabled version of your function
fact = memoize(factorial_rec)
# ... and use that, instead of the original ...
# See how long the bare function takes
print timer(factorial_rec, 100)
# The first call to the proxy will be slightly slower than the bare function
print timer(fact,100)
# But the second call with the same argument will be much faster
print timer(fact,100)
==================================================
Output:
Took 0.000393986701965 seconds ...
93326215443944152681699238856266700490715968264381621468592963895217599993229915608941463976156518286253697920827223758251185210916864000000000000000000000000
Took 0.000407934188843 seconds ...
93326215443944152681699238856266700490715968264381621468592963895217599993229915608941463976156518286253697920827223758251185210916864000000000000000000000000
Took 4.88758087158e-06 seconds ...
93326215443944152681699238856266700490715968264381621468592963895217599993229915608941463976156518286253697920827223758251185210916864000000000000000000000000
More information about the Python-list
mailing list