2012-07-14 65 views
2

我想創建一個存儲數學函數名稱,輸入(單個數字)和結果的字典。python:添加/添加動態鍵值:動態詞典中的值對

結構應該是這樣的cache = {procedure: {input:result}}

i.e. 

cache = {'factorial': {4:24, 10:3628800, 20:2432902008176640000}, 
     'square': {2:4, 5:25, 10:100} 
     'sum': {3:6, 5:10, 7:14}} 

def factorial(n): 
    #print "Running factorial" 
    result = 1 
    for i in range(2, n + 1): 
     result = result * i 
    return result 

def square(n): 
    result = n^2 
    return result 

def sum(n): 
    result = n * 2 
    return result 

我不想在這個意義上,它可能不知道哪個數學函數它將存儲值進行預創建緩存詞典。然後,我想創建一個名爲cached_execution的函數,該函數將首先檢查緩存是否已爲輸入調用函數,如果是,則返回存儲爲input:result對的值。

如果沒有,則計算操作,將其存儲在緩存中並返回該值。如果函數存在於緩存中,則應在其下創建另一個鍵/值對。如果不是,則爲該函數名稱創建一個新條目,並將輸入/結果的鍵/值存儲在該條目下。

cached_execution的結構很簡單,但我無法弄清楚如何附加到字典。看起來append不是字典結構允許的方法。我嘗試了各種不成功的事情。

欣賞幫助。

+1

附註:'n^2'不給你方塊,但是n XOR 2。你想'n ** 2'。 – DSM 2012-07-14 16:58:22

+0

你有什麼嘗試?你可以編輯添加你的代碼並指出問題出在哪裏? – 2012-07-14 17:08:30

+0

「...我無法弄清楚如何追加到字典中,似乎append不是字典結構允許的方法。」你不會追加到字典中,而是設置'key:value'對。如果你有一個字典'd'並且想要設置'4:24'對,你可以'd [4] = 24'。 – 2012-07-14 17:08:54

回答

4

你也可能想看看Memoize。有許多可能的實現,其中3個在Python.org wiki上。即使您編寫自己的版本,也可以查看其他人是如何攻擊該問題的。

+0

非常感謝您指導我閱讀該文檔。這正是我需要的。 – codingknob 2012-07-15 14:02:21

1
import pprint 

class MathFunctions(object) 

    def __init__(self): 
     self.cache = {} 

    def print_cache(self): 
     pprint.pprint(self.cache) 

    def factorial(self, n): 
     #print "Running factorial" 
     result = 1 
     for i in range(2, n + 1): 
      result = result * i 
     return result 

    def square(self, n): 
     result = n^2 
     return result 

    def sum(self,n): 
     result = n * 2 
     return result 

    def unknown(self,*args, **kwargs): 
     return "UNKNOWN" 

if __name__ == "__main__": 

    m = MathFunctions() 

    functions_to_run = [ 'sum', 'square', 'etc' ] 
    input_values  = [ 1, 3.3, 9 ] 

    for function in functions_to_run: 
     for input in input_values: 
      result = m.cache.get(function,{}).get(input,None) 

      if None == result: 
       if None == m.cache.get(function,None): 
        m.cache[function] = {} 
       m.cache[function][input] = getattr(m,function,m.unknown)(input) 
0

檢查了這一點!

cache={} 

def factorial(n): 
    result=1 
    for i in range(2, n+1): 
     result+=1 
    return result 

def square(n): 
    return n^2 

def sum(n): 
    return n*2 


def cached_execution(function,n): 
    if function in cache.keys():  
     if n in cache[function].keys(): 
      return cache[function][n] 
     else: 
      if function=='factorial': 
       cache['factorial'][n]=factorial(n) 
       return cache['factorial'][n] 
      elif function=='square': 
       cache['square'][n]=square(n) 
       return cache['square'][n] 
      elif function=='sum': 
       cache['sum'][n]=sum(n) 
       return cache['sum'][n] 
    else: 
     cache[function]={} 
     if function=='factorial': 
      cache['factorial']={} 
      cache['factorial'][n]=factorial(n) 
      return cache['factorial'][n] 
     elif function=='square': 
      cache['square']={} 
      cache['square'][n]=square(n) 
      return cache['square'][n] 
     elif function=='sum': 
      cache['sum']={} 
      cache['sum'][n]=sum(n) 
      return cache['sum'][n] 
     else: 
      cache[function]={}  
      cache[function][n]="Define_function" 
      return cache[function][n] 


cached_execution('sum',8) 
cached_execution('square',7) 
cached_execution('sum',5) 
cached_execution('factorial',10) 
cached_execution('log',10) 
print cache 

它使輸出爲:{'factorial': {10: 10}, 'sum': {8: 16, 5: 10}, 'square': {7: 5}, 'log': {10: 'Define_function'}

+0

您編輯了您的文章並修復了一個問題,但是如果尚未緩存,它仍然不會返回結果,只需計算並將其添加到下一次 – 2012-07-14 17:31:06

+0

現在...只需將緩存定義爲空白字典即可使用! ! – namit 2012-07-14 17:42:23

1

這裏是一個基於類的方法:

def factorial(x): 
    result = 1 
    for i in range(2, x+1): 
     result *= i 
    return result 


def square(x): 
    return x**2 


class CachedMath: 
    def __init__(self): 
     """create a cached result of function return values so that 
     if the same function is called with the same argument more 
     than once, the operation is not repeated 

     """ 
     self.cache = {} 

    def execute(self, func, number): 
     if func not in self.cache: 
      #if the function has never been used before 
      #create a spot in the cache for it 
      self.cache[func] = {} 

     if number in self.cache[func]: 
      #if this operation has been done before 
      #return the cached result 
      return self.cache[func][number] 
     else: 
      #otherwise perform the operation and store the result in cache 
      result = func(number) 
      self.cache[func][number] = result 
      return result 

ops = CachedMath() 
print ops.execute(factorial, 10) 
print ops.execute(factorial, 10) 
print ops.execute(square, 9) 

你可以通過執行方法添加新的功能,新的高速緩存。

如果你不想使用一個類,那麼這也似乎爲我工作:

def factorial(x): 
    result = 1 
    for i in range(2, x+1): 
     result *= i 
    return result 

cache = {} 
cache[factorial] = {2: 2, 4: 24, 10:362880} 
def do_math(func, number): 
    if number in cache[func]: 
     return cache[func][number] 
    else: 
     result = func(number) 
     cache[func][number] = result 
     return result 

print do_math(factorial, 10) 
print do_math(factorial, 5) 
0

這裏有你想要做什麼的簡單裝飾的版本。

def cached_execution(cache): 
    def cached_exec_decorator(func): 
     def check_cache(x): 
      try: 
       result = cache[func.__name__][x] 
      except KeyError: 
       result = func(x) 
       if func.__name__ not in cache: 
        cache[func.__name__] = {x : result} 
       else: 
        cache[func.__name__][x] = result 
      return result 
     return check_cache 
    return cached_exec_decorator 

用法示例:

cache = dict() 

# decorator for caching the function call 
# you have to pass it a dict to cache in 
@cached_execution(cache) 
def square(x): 
    print "Square is being evaluated!" 
    return n ** 2 

print square(5) # "Square is being evaluated!\n25" - square(5) isn't cached 
print square(5) # "25" - square(5) is cached 
print cache # {'square': {5: 25}} 

這種方法是語義要比您最初的描述和一些其他的答案中張貼我在寫這個,它隱藏了緩存機制的方法更好一點,所以你可以撥打square(x)而不是記得撥打cached_execution(square, x)

你也可以將它作爲可調用的類裝飾器來存儲它自己的緩存,而不需要提供對外部緩存字典的引用。我認爲這是由@Peter Rowell鏈接的memoize代碼片段所使用的方法 - 直到現在我還不知道該頁面或名稱。