今天我们来说一说递归,在说递归之前,我们先了解一下函数的闭包。
1.闭包
何为闭包,那就是在一个内部函数中,对外部作用域的变量进行引用,(并且一般外部函数的返回值为内部函数),那么内部函数就被认为是闭包。
例如:
def a():
x=0
y=0
def b(x1,y1):
nonlocal x,y
x+=x1
y+=y1
print(f"现在,x={x},y={y}")
return inner
闭包做的事可以这么概括:
①利用嵌套函数的外层作用域具有记忆能力这个特性。
②将内层函数作为返回值给返回。
知道了闭包,我们来说一说递归。
2.递归
递归正是通过闭包不断将自身函数作为返回值返回而做到的,说白了,递归做的事情就是自己调用自己,直至结束。
举个例子:
1加到100的例子
def a(n):
if n==1:
return 1
else:
return n+a(n-1)
print(a(100))
运行这串代码,我们不难得出答案为
5050
从上述代码中,我们不难看出,递归实际上是从最后开始一个一个的返回回原来的函数里,直到循环结束为止。这里,我们需要注意一个问题,那就是你的递归函数一定要有可以结束循环的语句,否则,你的函数就会一直运行下去,除非强行终止
例如:
def a(n):
if n>0:
print("trkczx")
n += 1
a(n)
print(a(1))
运行这串代码,我们会得到
trkczx
trkczx
trkczx
trkczx
trkczx
trkczx
trkczx
trkczx
trkczx
trkczx
trkczx
trkczx
trkczx
trkczx
trkczx
trkczx
trkczx
最后报出一个“RecursionError: maximum recursion depth exceeded while calling a Python object”的错误,告诉你进入了死循环,因此,递归一定要有结束语句。
3.斐波那契数列
下面我们看看斐波那契数列的代码
def a(n):
if n == 1 or n == 2:
return 1
else:
return a(n-1)+a(n-2)
n=int(input("n="))
print(a(n))
我们输入一个10进去,得到的结果为55,这是如何计算的呢?
首先,先进行了a(10),得到了a(8)+a(9),而a(8)和a(9)又重新代入a(n)这个函数中,最终得到55这个数据。
4.拓展:上楼梯问题
小朱同学今天上楼梯,每次只上1级或者2级,现有楼梯n级,问小朱同学上去有多少种方法。
此题我们如法炮制,修改一下斐波那契数列的代码我们便可求得此题的源代码。
def a(n):
if n == 1:
return 1
elif n == 2:
return 2
else:
return a(n-1)+a(n-2)
n=int(input("n="))
print(a(n))
5.最后,我郑重提醒,递归解决不了数字过大的问题,Python的递归深度是有限制的,默认值为1000。当递归深度超过1000时,就会报错。当然我们可以使用sys.setrecursionlimit()设置递归深度限制。
例子
def a(n):
if n == 1:
return 1
else:
return n * a(n - 1)
上面的例子是求n的阶乘,有退出条件n==1,因此并不是无限递归,但是当n太大时会产生Segmentation fault(分段错误),Python解释器崩溃,那么此时我们便可使用迭代的方法解决这个问题。