【问题标题】:recursive function python 3 'maximum recursion depth exceeded'递归函数python 3'超出最大递归深度'
【发布时间】:2017-10-08 08:33:40
【问题描述】:

我正在创建一个带有递归函数的 collat​​z 序列:

def collatz(n):
  if n%2 == 0:
    return int(n/2)
  else:   
    return int((3 * n)/2)

据我了解,递归函数是一个基本上调用自身的函数。下面我尝试使用以下方法创建递归函数:

def collatz(x):
    if x == 1:
        "Done"
    print(x)
    x = collatz(x)
    return(x)

本质上,变量 x 继续传递到我定义的 collatz 函数中,直到它达到 1。但是,每次我运行递归函数时,它都会重复打印 'x',然后我得到了

collatz(3)    
'RecursionError: maximum recursion depth exceeded in comparison' 

我的理解本质上是一个无限循环。我想通过将其重新分配给 x 到第一个 collatz() 的结果,它会返回新值并继续直到它达到 '1' 但我似乎无法到达那里。

任何帮助/提示/建议都会很棒!谢谢!

【问题讨论】:

  • 您收到错误是因为您从定义中调用函数 - 您尚未完成定义函数,您应该从函数外部调用它(缩进)。
  • 我不太听你的解释。函数的哪一部分没有定义?我刚刚对原始帖子进行了编辑,显示了我在哪里调用 collat​​z 函数。
  • 在手机上打字,抱歉..您在函数 collat​​z 中有 collat​​z(x),因此出现错误。在函数外部调用 collat​​z(x),这意味着不要缩进它以便成为您定义的函数的一部分。
  • 你会发现你没有复制你的示例函数。靠近计算机时会更新。
  • @mikey 他显然正在这样做,因为如果他没有这样做,那么他观察到的错误就是缺少输出。

标签: python python-3.x function recursion collatz


【解决方案1】:

递归函数具有所谓的“基本情况”和所谓的“递归情况”。基本情况是您应该停止递归并返回答案。

在这种情况下,基本情况是x==1

def collatz(x):
    if x == 1:
        return x

递归情况是其余时间

# continuing from above
    else:
        if n % 2 == 0:
            return collatz(int(n//2))
        else:
            return collatz(n*3 / 2)  # sicut. Note that the collatz sequence
                                     # uses 3n+1 here, not 3n/2 as in the question

注意我在下一个循环中通过collatz 更改x 的有效值,然后返回该新调用的结果。如果您不这样做,只需 return collatz(x),您将永远无法达到基本情况并永远递归。

【讨论】:

  • 与其他现代语言相比,Python 在递归方面做得特别差。这是一个有用的概念,但在生产代码中尽量避免使用它。在 haskell 中查看 this implementation
  • 注意 - 这更适合练习/学习,但我感谢您的帮助!
  • @Harris2018 我意识到了。递归对于学习对软件工程有更广泛的理解是非常必要的,但是 Python 缺乏对递归的某些优化(主要是尾调用消除),如果可以避免的话,这对于任何非玩具代码来说都是一个坏主意。
  • 对于像 collat​​z 序列这样的实例,如果我需要按照模式创建另一个序列,最好通过循环来避免递归?什么是最佳实践,我倾向于使用大型数据集,不想占用时间/内存/资源
  • @Harris2018 绝对更喜欢迭代序列而不是递归序列,是的。在这种情况下,我会做一些事情like this
【解决方案2】:

@Roee Gavirel

这是根据他上面的回答得出的最终答案:

def collatz(x):
    if x == 1:
        "Done"
    elif x%2 == 0:
        x = int(x/2)
        print(x)
        collatz(x)     
    else:
        x = int((3*x)+1)
        print(x)
        collatz(x)


collatz(3)

感谢大家的帮助!

【讨论】:

    【解决方案3】:

    您展示了同一个函数 collat​​z 的两个不同实现,而您需要将它们组合起来。

    def collatz(n):
        if x == 1:
            "Done"
        print(x)
        if n%2 == 0:
            collatz(int(n/2))
        else:   
            collatz(int((3 * n)/2))
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-07-09
      • 2011-12-31
      • 1970-01-01
      • 2011-01-24
      • 2016-12-10
      • 2020-07-13
      • 2021-02-07
      • 2017-03-18
      相关资源
      最近更新 更多