2012-04-07 43 views
3

我一直有使用Python(我是一個完整的福利局),在那裏,當我覺得它應該保存它不一遍又一遍存儲從計算的數據,但它再次程序的問題。我如何讓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 )「一遍又一遍,我想在打印時保存以供參考。

謝謝!

rofls

回答

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] 
+1

你是真棒!感謝您的快速響應!像夢一樣工作。現在,我將用我的其他更令人垂涎的(muhahaha)程序來嘗試它,看看它是否有效。如果沒有,我會很快回來! – rofls 2012-04-07 08:14:55

0

你可能只是將其分配到一個局部變量:

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

注:它還算即使g(x)與的x相同的值調用了兩次篩。對於保存計算甚至超出g範圍的版本,參見例如基思的回答。

4

這就是所謂的記憶化。幸運的是,有很多記憶化裝飾的,其中之一是在這裏: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表達應用於裝飾到它後面的函數)。

+0

我沒有嘗試過,因爲上面的工作,但謝謝!我仍然不明白在Python中內存是如何工作的,所以我很想知道哪個更高效或者它們是如何工作的。 – rofls 2012-04-07 08:16:30

+1

'@ memoized'的功能基本上是將'sieve'轉換成'saved_sieve',就地。 (這比這更復雜一點,因爲你不能*轉換函數,但你可以動態地創建新的函數。)它應該是效率相等的。 – 2012-04-07 08:48:53

+0

@rofls你對python內存有什麼不瞭解? – Marcin 2012-04-07 08:49:06

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