Python练习涉及函数,递归和类

时间:2017-06-10 17:41:38

标签: python oop recursion

我正在做一个练习,我要创建一个表示函数的类(写成lambda表达式)和几个涉及它们的方法。

我到目前为止写的是:

class Func():
    def __init__(self, func, domain):
        self.func = func
        self.domain = domain

    def __call__(self, x):
        if self.domain(x):
            return self.func(x)
        return None

    def compose(self, other):
        comp_func= lambda x: self.func(other(x))
        comp_dom= lambda x: other.domain(x) and self.domain(other(x))
        return Func(comp_func, comp_dom)

    def exp(self, k):
        exp_func= self
        for i in range(k-1):
            exp_func = Func.compose(exp_func, self)
        return exp_func 

如上所示,函数exp自身构成k-1次函数。现在我要编写一个递归版本的所述函数,采用相同的参数" self"和" k"。 但是,我很难弄清楚它是如何工作的。在我写的原始exp中,我可以访问原始函数" self"在所有迭代中,但是在创建递归函数时,我无法访问原始函数,并且每次迭代只能访问最新的组合函数。因此,举例来说,如果我尝试用自己创作自我一定次数,我会得到:

f= x+3
f^2= x+6
(f^2)^2= x+12

所以我们跳过了函数x + 9。

我如何解决这个问题?有没有办法继续保留对原始函数的访问权限?

更新

def exp_rec(self, k):
    if k==1:
        return self
    return Func.compose(Func.exp_rec(self, k-1), self)

1 个答案:

答案 0 :(得分:3)

这是一项练习,所以我不会提供答案。

在递归中,你想做两件事:

  • 确定并检查告诉您何时停止的“保护条件”;以及

  • 确定并计算告诉您下一个值的“递归关系”。

考虑一个简单的因子函数:

def fact(n):
    if n == 1:
        return 1

    return n * fact(n - 1)

在这个例子中,保护条件相当明显 - 这是唯一的条件语句!并且递归关系在return语句中。

对于你的练习,事情稍微不那么明显,因为目的是定义一个函数组合,而不是一个直的整数计算。但请考虑:

f = Func(lambda x: x + 3)

(这是你的例子。)你希望f.exp(1)与f相同,f.exp(2)为f(f(x))。那就在那里告诉你保护条件和复发关系:

保护条件是exp()仅适用于正数。这是因为exp(0)可能必须为不同的输入类型返回不同的东西(当f = Func(lambda s:s +'!')时,exp(0)返回什么?)。

因此测试exp(1),并让该条件成为原始lambda。

然后,当递归地定义exp(n + 1)时,让它成为原始 lambda与exp(n)的组合。

您需要考虑以下几点:首先,您的类实例具有与之关联的数据。该数据将在您的递归中“随身携带”,因此您不必递归传递这么多参数。其次,您需要确定Func.exp()是否创建一个新的Func(),或者它是否修改现有的Func对象。最后,考虑如何编写一个硬编码函数Func.exp2(),它只是构造了我们称之为Func.exp(2)的函数。这应该可以让你了解你的复发关系。

<强>更新

基于一些评论,我觉得我应该展示这段代码。如果要使用递归函数修改self对象,而不是返回一个新对象,则需要在修改之前“缓存”self中的值,如下所示: / p>

func = self.func
domain = self.domain

... recursive function modifies self.func and self.domain