python - 递归的中间结果

标签 python recursion functional-programming generator

我有一个问题,我需要生成一些自然递归计算的东西,但如果需要,我还需要能够询问递归中的中间步骤。

我知道我可以通过传递和改变列表或类似结构来做到这一点。然而,这对我来说看起来很难看,我确信一定有一种更简洁的方法,例如使用发电机。我理想中希望能够做的是:

intermediate_results = [f(x) for x in range(T)]
final_result = intermediate_results[T-1]

以有效的方式。虽然我的解决方案对性能并不关键,但我无法证明第一行中的大量冗余工作是合理的。在我看来,生成器非常适合这种情况,除了 f 从根本上来说更适合我的情况下的递归(至少在我看来,这与生成器完全相反,但也许我只是没有跳出框框思考得足够远)。

有没有一种简洁的 Pythonic 方式来做这样的事情,我只是不知道,或者我只需要投降并通过传递一个 来污染我的函数 f middle_results 列表,然后我将其作为副作用进行变异?

最佳答案

我有一个使用装饰器的通用解决方案。我们创建一个 Memoize 类,用于存储先前执行函数的结果(包括递归调用)。如果给定的参数已经被看到,则使用缓存的版本来快速查找结果。

自定义类比 lru_cache 具有优势,因为您可以看到结果。

from functools import wraps

class Memoize:
    def __init__(self):
        self.store = {}

    def save(self, fun):
        @wraps(fun)
        def wrapper(*args):
            if args not in self.store:
                self.store[args] = fun(*args)
            return self.store[args]
        return wrapper

m = Memoize()

@m.save
def fibo(n):
    if n <= 0: return 0
    elif n == 1: return 1
    else: return fibo(n-1) + fibo(n-2)

然后在运行不同的东西之后,您可以看到缓存包含的内容。当您运行 future 的函数调用时,m.store 将用作查找,因此不需要重做计算。

>>> f(8)
21
>>> m.store
{(1,): 1,
 (0,): 0,
 (2,): 1,
 (3,): 2,
 (4,): 3,
 (5,): 5,
 (6,): 8,
 (7,): 13,
 (8,): 21}

您可以修改 save 函数以使用函数名称和参数作为键,以便多个函数结果可以存储在同一个 Memoize 类中.

关于python - 递归的中间结果,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/66321457/

相关文章:

python - Django 1.9 在列表中查找属性等于某个值的对象

c - C中的递归,需要一些解释

list - Erlang 中的列表分区和拆分之间有什么区别吗?

java - 看到两个字符串是通过递归互相映射

recursion - 两种不同类型的 OCaml 递归函数

java - 在 Java 8+ 中,流中只允许使用单参数方法引用

scala - Lazy foldRight 提前终止混淆

python - 找到比给定的最大距离更近的所有点对

python - 在 Maya 中获取对象 Axis 指向的方向

python - cp -r from_dir/* to_dir 与 python