我想创建一个存储数学函数名称,输入(单个数字)和结果的字典。
结构应该类似于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不是字典结构允许的方法。我尝试了各种各样的事情但没有成功。
感谢帮助。
答案 0 :(得分:4)
您可能还想查看Memoize。有许多可能的实现,其中3个在Python.org wiki上。即使您编写自己的版本,也可以了解其他人如何攻击该问题。
答案 1 :(得分: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)
答案 2 :(得分: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)
只需使用execute方法即可为新函数添加新缓存。
如果您不想使用课程,那么这似乎对我有用:
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)
答案 3 :(得分: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'}
答案 4 :(得分: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)
。
你可能也可以将它作为一个可调用的类装饰器来存储它自己的缓存,而不是需要提供对外部缓存dict的引用。我认为这是@Peter Rowell链接的memoize代码片段使用的方法 - 我到目前为止还不知道该页面或名称。