我刚开始学习Python,我不知道什么是内存化,也不知道如何使用它。另外,我可以举一个简单的例子吗?
当前回答
下面是一个解决方案,将工作与列表或dict类型参数没有抱怨:
def memoize(fn):
"""returns a memoized version of any function that can be called
with the same list of arguments.
Usage: foo = memoize(foo)"""
def handle_item(x):
if isinstance(x, dict):
return make_tuple(sorted(x.items()))
elif hasattr(x, '__iter__'):
return make_tuple(x)
else:
return x
def make_tuple(L):
return tuple(handle_item(x) for x in L)
def foo(*args, **kwargs):
items_cache = make_tuple(sorted(kwargs.items()))
args_cache = make_tuple(args)
if (args_cache, items_cache) not in foo.past_calls:
foo.past_calls[(args_cache, items_cache)] = fn(*args,**kwargs)
return foo.past_calls[(args_cache, items_cache)]
foo.past_calls = {}
foo.__name__ = 'memoized_' + fn.__name__
return foo
请注意,通过在handle_item中实现您自己的哈希函数,这种方法可以自然地扩展到任何对象。例如,为了使这种方法适用于一个接受set作为输入参数的函数,你可以在handle_item中添加:
if is_instance(x, set):
return make_tuple(sorted(list(x)))
其他回答
记忆是将函数转换为数据结构的过程。通常,人们希望增量地、惰性地进行转换(根据给定的域元素——或“键”的要求)。在惰性函数语言中,这种惰性转换可以自动发生,因此可以在没有(显式)副作用的情况下实现内存化。
下面是一个解决方案,将工作与列表或dict类型参数没有抱怨:
def memoize(fn):
"""returns a memoized version of any function that can be called
with the same list of arguments.
Usage: foo = memoize(foo)"""
def handle_item(x):
if isinstance(x, dict):
return make_tuple(sorted(x.items()))
elif hasattr(x, '__iter__'):
return make_tuple(x)
else:
return x
def make_tuple(L):
return tuple(handle_item(x) for x in L)
def foo(*args, **kwargs):
items_cache = make_tuple(sorted(kwargs.items()))
args_cache = make_tuple(args)
if (args_cache, items_cache) not in foo.past_calls:
foo.past_calls[(args_cache, items_cache)] = fn(*args,**kwargs)
return foo.past_calls[(args_cache, items_cache)]
foo.past_calls = {}
foo.__name__ = 'memoized_' + fn.__name__
return foo
请注意,通过在handle_item中实现您自己的哈希函数,这种方法可以自然地扩展到任何对象。例如,为了使这种方法适用于一个接受set作为输入参数的函数,你可以在handle_item中添加:
if is_instance(x, set):
return make_tuple(sorted(list(x)))
只是想对已经提供的答案进行补充,Python装饰器库有一些简单但有用的实现,也可以记住“不可哈希类型”,不像functools.lru_cache。
与传递关键字参数的顺序无关的位置参数和关键字参数的解决方案(使用inspect.getargspec):
import inspect
import functools
def memoize(fn):
cache = fn.cache = {}
@functools.wraps(fn)
def memoizer(*args, **kwargs):
kwargs.update(dict(zip(inspect.getargspec(fn).args, args)))
key = tuple(kwargs.get(k, None) for k in inspect.getargspec(fn).args)
if key not in cache:
cache[key] = fn(**kwargs)
return cache[key]
return memoizer
类似的问题:在Python中识别用于内存化的等效可变参数函数调用
记忆基本上是保存用递归算法完成的过去操作的结果,以便在以后需要进行相同的计算时减少遍历递归树的需要。
参见http://scriptbucket.wordpress.com/2012/12/11/introduction-to-memoization/
Python中的斐波那契内存示例:
fibcache = {}
def fib(num):
if num in fibcache:
return fibcache[num]
else:
fibcache[num] = num if num < 2 else fib(num-1) + fib(num-2)
return fibcache[num]
推荐文章
- 使用python创建一个简单的XML文件
- APT命令行界面式的yes/no输入?
- 如何打印出状态栏和百分比?
- 在Python中获取大文件的MD5哈希值
- 在Python格式字符串中%s是什么意思?
- 如何循环通过所有但最后一项的列表?
- python用什么方法避免默认参数为空列表?
- ValueError: numpy。Ndarray大小改变,可能表示二进制不兼容。期望从C头得到88,从PyObject得到80
- Anaconda /conda -安装特定的软件包版本
- 我在哪里调用Keras的BatchNormalization函数?
- 打印测试执行时间并使用py.test锁定缓慢的测试
- 插入一行到熊猫数据框架
- 要列出Pandas DataFrame列
- 在Django模型中存储电话号码的最佳方法是什么?
- 从导入的模块中模拟函数