3

我一直在使用 Python 中的程序(我是一个完整的新手)遇到问题,它不存储来自计算的数据,并且当我觉得它应该保存它时一遍又一遍地执行它。我怎样才能让 Python 保存答案,这样它就不会一遍又一遍地计算程序?

前任:

import prime
def g(x):
    i=0
    while i<len(prime.sieve(x)):
        print str(prime.sieve(x)[i])+' is prime'
        i=i+1

这是“主要”模块,以防有人想要编译它:

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

无论如何,第一段代码一遍又一遍地计算列表“prime.sieve(x)”,我想保存它以供打印时参考。

谢谢!

罗弗斯

4

4 回答 4

4
saved_sieve_map = {}
def saved_sieve(x):
  if x not in saved_sieve_map:
    saved_sieve_map[x] = sieve(x)
  return saved_sieve_map[x]
于 2012-04-07T07:38:27.907 回答
4

这称为记忆。幸运的是,有很多 memoization 装饰器,其中之一在这里:http ://wiki.python.org/moin/PythonDecoratorLibrary#Memoize

示例用法是:

@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)

@memoized表达式将装饰器应用于它后面的函数)。

于 2012-04-07T07:41:48.797 回答
0

您可能只是将其分配给局部变量:

i=0
saveit = prime.sieve(x)
while i<len(saveit):
    print str(saveit[i])+' is prime'
    i=i+1

注意:即使g(x)使用相同的值调用两次,它仍然会计算筛子x。对于确实保存计算甚至超出范围的版本,g请参见例如 Keith 的答案。

于 2012-04-07T07:40:34.163 回答
0

此函数可用于消除递归复杂性。

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

无论如何,这是我对筛子的实现,它应该比你的运行得更快。

@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
于 2012-04-07T08:03:31.327 回答