How do I store the results of a calculation in Python so that my program doesn't calculate the same thing twice?
I'm having trouble with Python programs (I'm a complete newb) where it doesn't store data from calculations and does it over and over again when it feels like it should have saved it. How can I get Python to save the answer so that it doesn't calculate the program over and over?
Example:
import prime
def g(x):
i=0
while i<len(prime.sieve(x)):
print str(prime.sieve(x)[i])+' is prime'
i=i+1
Here's the "prime" module in case anyone wants to compile this:
def sieve(max):
#Takes in a number, and returns all primes between 2 and that number
#Start with all of the numbers
primes = range(2,max+1)
#Start running through each number
for i in primes:
#Start with double the number, and
j = 2
#remove all multiples
while i * j <= primes[-1]:
#As long as the current multiple of the number
#is less than than the last element in the list
#If the multiple is in the list, take it out
if i * j in primes:
primes.remove(i*j)
j=j+1
return primes
Anyway, the first bit of code is calculating the "prime.sieve (x)" list over and over again, and I want to keep it for reference when printing. In the meantime, there is no need to know about it. ”
Thank!
rofls
source to share
This is called memoization. Fortunately, there are many memory decorators and one of them is located here: http://wiki.python.org/moin/PythonDecoratorLibrary#Memoize
Usage example:
@memoized
def fibonacci(n):
"Return the nth fibonacci number."
if n in (0, 1):
return n
return fibonacci(n-1) + fibonacci(n-2)
print fibonacci(12)
(the expression @memoized
applies the decorator to the function following it).
source to share
You can simply assign it to a local variable:
i=0
saveit = prime.sieve(x)
while i<len(saveit):
print str(saveit[i])+' is prime'
i=i+1
Note: it still computes the sieve even if g(x)
called twice with the same value x
. For a version that keeps the calculation even outside the scope g
, see Keith's answer for example.
source to share
This function can be used to eliminate recursive complexity.
from functools import wraps
def memo(func):
cache = {}
@wraps(func)
def wrap(*args):
if args not in cache:
cache[args] = func(*args)
return cache[args]
return wrap
Anyway, this is my implementation of a sieve that should be faster than yours.
@memo
def sieve(end):
import itertools
lng = ((end/2)-1+end%2)
sieve = [True]*(lng+1)
for i in itertools.ifilter(lambda z: sieve[z],xrange(int(end**0.5) >> 1)):
n=len(sieve[int((i*(i + 3) << 1) + 3): int(lng): int((i << 1) + 3)])
sieve[int((i*(i + 3) << 1) + 3): int(lng): int((i << 1) + 3)]=[False]*n
return sum([(x << 1) + 3 for x in itertools.compress(xrange(lng),sieve)])+2
source to share