为了账号安全,请及时绑定邮箱和手机立即绑定

为什么递归函数fact(n)少个return会报错?

为什么递归函数fact(n)少个return会报错?

else_if 2016-06-09 20:13:30
def fact(n):     if n==1:         return 1     n*fact(n-1)
查看完整描述

4 回答

已采纳
?
清波

TA贡献165条经验 获得超90个赞

首先贴出报错信息:

RecursionError: maximum recursion depth exceeded

递归错误:超出最大递归深度


好,这说明两个问题,其一 Python 对递归的深度有限制, 其二 这个函数超出了这个限度。

先说下后者吧,为什么去掉 return  之后会 使这个函数超出了 Python 的最大递归深度呢, 这是因为 return 有两个属性:

1 返回值,2 结束函数执行。 如果去掉了 return 这个递归函数就会无限递归下去,大致执行效果如下:

fact(5)

## 没有去掉 return 时:
fact(5) = 5 * fact(4)
fact(5) = 5 * 4 * fact(3)
fact(5) = 5 * 4 * 3 * fact(2)
fact(5) = 5 * 4 * 3 * 2 * fact(1)
fact(5) = 5 * 4 * 3 * 2 * 1 ## 此时fact函数判断出参数为1 直接return 1 并且退出了函数,也就是打断了递归。

## 去掉 return 时:
fact(5) = 5 * fact(4)
fact(5) = 5 * 4 * fact(3)
fact(5) = 5 * 4 * 3 * fact(2)
fact(5) = 5 * 4 * 3 * 2 * fact(1)
fact(5) = 5 * 4 * 3 * 2 * 1 * fact(-1) #这里是关键,去掉了return,致使参数无限的递减下去而不终结
fact(5) = 5 * 4 * 3 * 2 * 1 * -1 * fact(-2)
.
.
.
fact(5) = 5 * 4 * 3 * 2 * 1 * -1 * ... * -n * fact(-n-1)
.
.
.

## 所以最终就突破了 最大递归深度。



现在我们说下, Python 对递归深度的限制, 一般来说是 1000, 好像也有人说 是 997 什么的,大概就在这个范围。

那么为什么Python 会对递归 这个 看起来特别强大的 解决问题的思想加以限制呢?

这就要说到, Python 中递归的原理了,简单来说就是每一次递归都建立一个函数,也就是说在内存中 占用一块地址,如果不加以限制的话, 就会导致 内存溢出,这时候程序 就会报错了, 所以Python 对递归的深度加以限制。

Python 也给出了 改变这个限制的方法:

import sys

sys.setrecursionlimit(depth) ## depth 为int 类型, 传进去就可以改变递归的最大深度了。

不建议这么做,如果一个问题需要突破递归深度才能解决,那么递归也许就不是这个问题的最优解了, 建议用其他方式解决问题,而不是轻易改变递归深度。

查看完整回答
1 反对 回复 2016-06-10
  • else_if
    else_if
    这个函数为什么不会无限递归下去? def move(n, a, b, c): if n==1: print a,'-->',c return move(n-1,a,c,b)
  • 昨天无所谓3300770
    昨天无所谓3300770
    这程序就算n*fact(n-1)不return也不会无限递归下去好吗,无限递归只是因为递归程序没有出口,这程序有出口n=1
  • 清波
    清波
    额,这位仁兄这是在说哪个程序?我没看出来 去掉 return 之后的 程序还有别的出口, 如果仁兄确实 验证过,请给出代码。
点击展开后面3
?
weibo_曦禅_03461137

TA贡献3条经验 获得超1个赞



575af5a100016b8005000299.jpg

575af5a200018dcd05000042.jpg

这两个的报错是不一样的,一个没有返回值,一个是超出最大限制了。

查看完整回答
反对 回复 2016-06-11
?
else_if

TA贡献2条经验 获得超0个赞

这个函数为什么不会无限递归下去?

def move(n, a, b, c):

    if n==1:

        print a,'-->',c

        return 

    move(n-1,a,c,b)


查看完整回答
反对 回复 2016-06-10
?
weibo_曦禅_03461137

TA贡献3条经验 获得超1个赞

也不一定会报错,我调试了,如果没有return,就没有返回值,函数运行的结果就是空值。


查看完整回答
反对 回复 2016-06-09
  • 4 回答
  • 0 关注
  • 2006 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信