【发布时间】:2019-08-09 00:28:30
【问题描述】:
我正在练习用 python 生成斐波那契数列,并遵循How do I print a fibonacci sequence to the nth number in Python? 的记忆示例。
然后我遇到了一个有趣的区别,即使用 return one-liner 而不是。例如,示例代码如下所示。在第一个示例中,我们没有使用 return one-liner,它运行得非常快,而在第二个示例中,我们使用了 return one-liner,它运行得非常慢。
他们不应该是一样的吗?
没有单行
def memoize(func):
memo = dict()
def decorated(n):
if n not in memo:
memo[n] = func(n)
return memo[n]
return decorated
@memoize
def fib(n):
if n<=1:
return 1
else:
return fib(n-1) + fib(n-2)
print([ fib(i) for i in range(100,110)]) # runs very fast
单线返回
def memoize(func):
memo = dict()
def decorated(n):
return func(n) if n not in memo else memo[n]
return decorated
@memoize
def fib(n):
if n<=1:
return 1
else:
return fib(n-1) + fib(n-2)
print([ fib(i) for i in range(100,110)]) # very slow
问题
他们不应该是一样的吗?
为什么返回一班轮比另一班慢得多?
我们可以用不同的措辞写一个单行,以使其同样快吗?
【问题讨论】:
-
单行不修改
memo的内容。 -
2.第二个速度较慢,因为您大概不会在
memo中保存任何内容。 -
正确的单行应该类似于
return memo[n] if n in memo else memo.setdefault(n, func(n))。 (如果查找实际上会成功,则条件表达式会阻止评估func(n)。) -
如果您关心代码行,我可以将您的整个
memorize函数压缩为一行:from functools import lru_cache as memorize。这是用 c 编写的,比在 python 中重现的任何东西都要快得多。 docs.python.org/3/library/functools.html#functools.lru_cache -
@astro123 文档说你必须使用
@lru_cache(maxsize=<integer value or None>)而不是简单的@lru_cache。
标签: python