Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/350.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
涉及函数、递归和类的Python练习_Python_Oop_Recursion - Fatal编程技术网

涉及函数、递归和类的Python练习

涉及函数、递归和类的Python练习,python,oop,recursion,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.fun

我正在做一个练习,其中我将创建一个表示函数(编写为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”,但是,在生成递归函数时,我失去了对原始函数的访问权,并且每次迭代都只能访问最近合成的函数。例如,如果我试着用self创作self,我会得到:

f= x+3
f^2= x+6
(f^2)^2= x+12
所以我们跳过了函数x+9

我该怎么做?是否有办法保留对原始功能的访问权限

更新:


这是一个练习,所以我不提供答案

在递归中,您需要做两件事:

  • 确定并检查“防护条件”,告知您何时停止;及

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

考虑一个简单的阶乘函数:

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
中的值之前“缓存”,如下所示:

func = self.func
domain = self.domain

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

IMHO如果您必须将lambda分配给变量,那么最好从中创建一个闭包(即使用
def funcname(x):
而不是
funcname=lambda x:…
说明说明我将使用lambda表达式。好吧,那么请记住:谢谢你的回答。但是这并不能真正让我知道如何前进,因为正如你所说,我应该让exp(n+1)是原始lambda函数的组合,但如何访问“原始”函数?exp可以接受的唯一参数是“self”和“k”显然,我没有得到关于原始函数的任何信息,因此递归必须接受原始函数的某些版本。因此,在第一次迭代之后,exp将不再记得原始lambda函数,而只记得直到某个k的组合。那么我如何组合exp(n)使用它?self不是在它里面的某个地方有函数吗?一开始。但只有在递归的第一步中。在第一步中,你用self组合self,创建self^2。然后你将它传递到递归的下一步,因此self现在是self^2。如果你再次尝试用self组合它,你会得到self^4而不是self^3。这是假设的您已经决定
exp()
修改self(而不是返回单独的对象)。在这种情况下,在递归之前,将lambda函数存储在局部变量中。[编辑]我为演示添加了一个更新。我不希望修改原始自我。但我不能将同一个自我传递到递归的下一步,否则我不会真正做任何事情。当我在exp中调用exp时,我必须在合成版本的自我上调用它。然后在下一步,exp不知道原始自我是什么。
func = self.func
domain = self.domain

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