记忆和功能跟踪
Memoization and Function Tracking
我正在尝试跟踪函数 运行 的次数,并使用记忆来避免不必要地 运行 调用该函数。我不明白为什么,但似乎 memoization 正在为大多数值存储两个相同的值。
def track(f):
def wrapper(arg):
wrapper.count += 1
print(arg)
return f(arg)
wrapper.count = 0
return wrapper
def memoize(f):
memo = {}
def wrapper(arg):
if arg not in memo:
memo[arg] = f(arg)
return memo[arg]
return wrapper
@track
@memoize
def fib(n):
return n if n in (0,1) else fib(n-1) + fib(n-2)
print('Result:', fib(10), '\nCount:', fib.count)
结果应该是
10
9
8
7
6
5
4
3
2
1
0
Result: 55
Count: 11
出于某种原因,对于小于 9 的所有内容,它都会给出双倍的结果。计数实际上返回 19。我们将不胜感激任何帮助。
您需要将 memoize
移动到 track
:
def track(f):
@memoize
def wrapper(arg):
wrapper.count += 1
print(arg, end=' ')
return f(arg)
wrapper.count = 0
return wrapper
def memoize(f):
memo = {}
def wrapper(arg):
if arg not in memo:
memo[arg] = f(arg)
return memo[arg]
return wrapper
@track
def fib(n):
return n if n in (0,1) else fib(n-1) + fib(n-2)
print('Result:', fib(10), '\nCount:', fib.count)
10 9 8 7 6 5 4 3 2 1 0 Result: 55
Count: 11
通过向 track
添加额外的参数,您可以控制是否要使用 memoize
装饰器。在这种情况下,您应该使用 functools.wraps
:
from functools import wraps
def track(is_memoized):
def dec(f):
def wrapper(arg):
wrapper.count += 1
print(arg, end=' ')
return f(arg)
wrapper.count = 0
if is_memoized:
wrapper = memoize(wrapper)
return wrapper
return dec
def memoize(f):
memo = {}
@wraps(f)
def wrapper(arg):
if arg not in memo:
memo[arg] = f(arg)
return memo[arg]
return wrapper
@track(is_memoized=True)
def fib(n):
return n if n in (0,1) else fib(n-1) + fib(n-2)
print('Result:', fib(10), '\nCount:', fib.count)
10 9 8 7 6 5 4 3 2 1 0 Result: 55
Count: 11
@track(is_memoized=False)
def fib(n):
return n if n in (0,1) else fib(n-1) + fib(n-2)
print('Result:', fib(5), '\nCount:', fib.count)
5 4 3 2 1 0 1 2 1 0 3 2 1 0 1 Result: 5
Count: 15
我正在尝试跟踪函数 运行 的次数,并使用记忆来避免不必要地 运行 调用该函数。我不明白为什么,但似乎 memoization 正在为大多数值存储两个相同的值。
def track(f):
def wrapper(arg):
wrapper.count += 1
print(arg)
return f(arg)
wrapper.count = 0
return wrapper
def memoize(f):
memo = {}
def wrapper(arg):
if arg not in memo:
memo[arg] = f(arg)
return memo[arg]
return wrapper
@track
@memoize
def fib(n):
return n if n in (0,1) else fib(n-1) + fib(n-2)
print('Result:', fib(10), '\nCount:', fib.count)
结果应该是
10
9
8
7
6
5
4
3
2
1
0
Result: 55
Count: 11
出于某种原因,对于小于 9 的所有内容,它都会给出双倍的结果。计数实际上返回 19。我们将不胜感激任何帮助。
您需要将 memoize
移动到 track
:
def track(f):
@memoize
def wrapper(arg):
wrapper.count += 1
print(arg, end=' ')
return f(arg)
wrapper.count = 0
return wrapper
def memoize(f):
memo = {}
def wrapper(arg):
if arg not in memo:
memo[arg] = f(arg)
return memo[arg]
return wrapper
@track
def fib(n):
return n if n in (0,1) else fib(n-1) + fib(n-2)
print('Result:', fib(10), '\nCount:', fib.count)
10 9 8 7 6 5 4 3 2 1 0 Result: 55
Count: 11
通过向 track
添加额外的参数,您可以控制是否要使用 memoize
装饰器。在这种情况下,您应该使用 functools.wraps
:
from functools import wraps
def track(is_memoized):
def dec(f):
def wrapper(arg):
wrapper.count += 1
print(arg, end=' ')
return f(arg)
wrapper.count = 0
if is_memoized:
wrapper = memoize(wrapper)
return wrapper
return dec
def memoize(f):
memo = {}
@wraps(f)
def wrapper(arg):
if arg not in memo:
memo[arg] = f(arg)
return memo[arg]
return wrapper
@track(is_memoized=True)
def fib(n):
return n if n in (0,1) else fib(n-1) + fib(n-2)
print('Result:', fib(10), '\nCount:', fib.count)
10 9 8 7 6 5 4 3 2 1 0 Result: 55
Count: 11
@track(is_memoized=False)
def fib(n):
return n if n in (0,1) else fib(n-1) + fib(n-2)
print('Result:', fib(5), '\nCount:', fib.count)
5 4 3 2 1 0 1 2 1 0 3 2 1 0 1 Result: 5
Count: 15