Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/352.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_Function_Recursion_Nested_Depth - Fatal编程技术网

如何使用python避免嵌套函数中的深度递归

如何使用python避免嵌套函数中的深度递归,python,function,recursion,nested,depth,Python,Function,Recursion,Nested,Depth,假设我们有这个代码: a = 1 def func1(): if a == 1: func2() def func2(): if a == 1: func3() def func3(): func1() 有没有一种方法可以让func3调用func1,使其脱离已经发生的“父函数”?意思是,回到“递归深度0”,好像它是从新开始的 谢谢大家! 不确定要在何处停止递归,但这可能是一个很好的起点: def func1(parents = []

假设我们有这个代码:

a = 1

def func1():
    if a == 1:
        func2()

def func2():
    if a == 1:
        func3()

def func3():
    func1()
有没有一种方法可以让func3调用func1,使其脱离已经发生的“父函数”?意思是,回到“递归深度0”,好像它是从新开始的


谢谢大家!

不确定要在何处停止递归,但这可能是一个很好的起点:

def func1(parents = []):
    print "func1"
    if func1 not in parents:
        parents.append(func1)
        func2(parents)

def func2(parents = []):
    print "func2"
    if func2 not in parents:
        parents.append(func2)
        func3(parents)

def func3(parents = []):
    print "func3"
    if func3 not in parents:
        parents.append(func3)
        func1(parents)

func1()
输出:

func1
func2
func3
func1
有些语言提供,这相当于在创建新的堆栈框架之前扔掉以前的堆栈框架。只有当递归调用是发生的最后一个操作时(否则您需要堆栈帧,因为它指向其余的操作),这才可能发生。然而,Python没有

您有两个选择:

  • 如果函数是递归的,但递归不是通过尾部调用完成的,那么通常通过向函数签名添加参数来实现。(不过,您的示例中的代码已经是这种形式了。)一旦所有的递归都通过尾部调用完成,通常很容易实现
  • 如果希望避免执行上述操作,还可以将代码转换为用于存储内容的迭代样式,因为堆栈的大小或多或少是无界的,而调用堆栈通常非常小(这就是导致递归深度限制的原因)
  • 请注意,当您有三个递归调用的函数时,这两件事都比较棘手。但是总体的想法是提出新的代码,在不使用递归的情况下保留旧代码的行为,并且很明显,尽管一般模式(上面链接的)保持不变,但是如何做到这一点将根据起始代码的不同而有所不同

    在您的例子中,代码要么进入无限循环,要么不进入无限循环,这取决于
    a
    ,因此

     a = 1
    
     def func3():
         while a == 1:
           pass
    
     func3()
    
    就够了


    作为旁注:对于某些算法,可以减少调用次数。如果函数的大型输入的结果总是由重复计算()的较小输入的结果组成,则可以保留返回值的全局缓存,并在进行新调用之前检查缓存。通用备忘录代码可以使用Python编写

    如果您想重复运行
    func1
    func2
    func3
    的循环,但不想让它无限递归,您可能希望使用循环而不是递归

    尝试:


    检查这个你在寻找答案吗?在任何情况下,如果你更多地在观察层面上描述你的问题,你可能会得到更好的答案(比如“这种情况对我不好,因为我得到了太深的递归错误”或“因为它花费了太多时间”或“因为我的结果是错误的”或类似)。可能有完全不同的方法来解决您最初的问题,而不是您所想的。谢谢大家。我实际上在寻找一个类似于建议代码的解决方案。我使用的是一个非常无序的扩展代码,可以简化为给定的示例。因此,我需要一个func3(),它可以同时完成“结束递归”和再次调用func1。谢谢大家,我将学习并尝试答案,然后尝试它们,确认哪一个解决了问题//接受它。这对我来说是件困难的事情,所以可能需要几天的时间,谢谢你所做的一切。非常感谢你的回答。但是我不明白你发布的代码如何解决这个问题;当a==1时,函数仍然将自己嵌套在另一个函数中(直到a=!1)。您如何做到这一点,使无限循环不会达到最大深度递归?我已经更新了代码示例。澄清一下,在我的示例中没有func1或func2,func3从不调用任何东西,因此没有嵌套。仍然存在一个无限循环,因为您从未中断while循环。如果您需要保留其他功能,您可能需要在问题中包含其中的一些功能。您不能只保留原始的调用序列,并以某种方式避免堆栈溢出,但您可以重写代码,使其以更少的函数调用完成相同的操作。递归什么时候结束?基本情况是什么?这些函数的作用是什么?非常感谢您的回答。其思想不是停止递归,而是保持递归继续,而不在另一个函数中嵌套越来越多的函数,直到最终“超过最大递归深度”。理想情况下,脚本将在func3中“结束”,然后在func1中重新开始,由func3调用。。。
    def func1():
        pass # do stuff
    
    def func2():
        pass # do more stuff
    
    def func3():
        pass # something completely different
    
    a = 1
    
    while a == 1: # this will loop indefinately, unless one of the functions chages "a"
        func1()
        func2()
        func3()