[英]Recursive definition of arithmetic operators: How to memoize / cache?
所有算術運算符都基於所有自然數都有后繼這一事實。 出於教育目的,我將這個想法實現為 Python 函數:
# recursive definition of arithmetic operators
a = 2
b = 3 # larger numbers won't work: RecursionError
def successor(n):
""" returns n + 1. All other functions use successor recursively """
return n + 1
def sum(n, m):
""" sum a + b """
if m == 0:
return n
if m == 1:
return successor(n)
else:
return successor(sum(n, m - 1))
print(f"sum({a}, {b}) = {sum(a,b)}")
def product(n, m):
""" multiplication n*m"""
if m == 0:
return 0
elif m == 1:
return sum(n, 0)
else:
return sum(product(n, m - 1), n)
print(f"product({a}, {b}) = {product(a, b)}")
def power(n, m):
""" power n**m"""
if m == 0:
return 1
elif m == 1:
return product(n, 1)
else:
return product(power(n, m - 1), n)
print(f"power({a}, {b}) = {power(a, b)}")
def up_arrow_2(n, m):
""" up_arrow operator 2nd degree: n**(n**( ....) m times """
if m == 0:
return 1
elif m == 1:
return power(n, 1)
else:
return power(up_arrow_2(n, m - 1), n)
print(f"up_arrow_2({a}, {b}) = {up_arrow_2(a, b)}")
def up_arrow_3(n, m):
""" up_arrow operator 3rd degree"""
if m == 0:
return 1
elif m == 1:
return up_arrow_2(n, 1)
else:
return up_arrow_2(up_arrow_3(n, m - 1), n)
print(f"up_arrow_3({a}, {b}) = {up_arrow_3(a, b)}")
這適用於最多a=2
和b=3
的數字,然后在計算up_arrow_3(2, 4)
時會發生maximum recursion depth exceeded
(原因很明顯)。
如果我將行return n**m
作為power
function 中的第一行插入,則可以計算出更大的數字。 因此,緩存中間結果似乎是一個很有前途的解決方案。
為了擴展到更大的數字,我嘗試使用裝飾器 class 進行記憶,例如
class Memoize:
def __init__(self, fn):
self.fn = fn
self.memo = {}
def __call__(self, *args):
if args not in self.memo:
self.memo[args] = self.fn(*args)
return self.memo[args]
並裝飾功能 - 沒有成功。
我正在尋找一個想法,如何編寫另一個裝飾器來執行所需的緩存並允許更大的輸入數字 a、b。
以下代碼將解決您的問題。
def memoize(func):
cache = {}
def memoize_inner(*args, **kwargs):
str_args = f"{args}{kwargs}"
return cache.get(str_args, func(*args, **kwargs))
return memoize_inner
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.