函数递归指的是重复 “直接调用或间接调用” 函数本身,这是一种函数嵌套调用的表现形式。
- 直接调用: 指的是在函数内置,直接调用函数本身。
- 间接调用: 两个函数之间相互调用间接造成递归。
直接调用:
def foo():
print('from foo')
foo()
间接调用:
def foo():
print('from foo')
bar()
def bar():
print('from bar')
foo()
foo()
了解:
python中有递归默认深度: 限制递归次数
998, 1000
PS: 但是在每一台操作系统中都会根据硬盘来设置默认递归深度。
获取递归深度: 了解
sys.getrecursionlimit()
设置递归深度: 了解
sys.setrecursionlimit(深度值)
注意: 单纯的递归调用时没有任何意义的。
想要递归有意义,必须遵循两个条件:
- 递推:
指的是重复地执行, 每一次执行都要拿到一个更接近于结果的结果,
递推必须要有一个终止条件,否则无限递归。
- 回溯:
当递推找到一个终止条件后,开始一步一步往上回溯。
age(5) == age(4) + 2
age(4) == age(3) + 2
age(3) == age(2) + 2
age(2) == age(1) + 2
age(1) == 18 # 回溯终止的结果
#result:age(n) = age(n - 1) + 2
方式一:
def age(n):
if n == 18
return 18
else:
return age(n - 1) + 2 #age2
res=age(5)
print(res)
>>>26
方式二:#三元表达式
def age(n):
18 if n == 18 else age(n-1)+2
res=age(5)
print(res)
例子:
某公司四个员工坐在一起,问第四个人薪水,他说比第三个人多1000,问第三个人薪水,第他说比第二个人多1000,问第二个人薪水,他说比第一个人多1000,最后第一人说自己每月5000,请问第四个人的薪水是多少?
思路解析:
要知道第四个人的月薪,就必须知道第三个人的,第三个人的又取决于第二个人的,第二个人的又取决于第一个人的,而且每一个员工都比前一个多一千,数学表达式即:
salary(4)=salary(3)+1000
salary(3)=salary(2)+1000
salary(2)=salary(1)+1000
salary(1)=5000
总结为:
salary(n)=salary(n-1)+1000 (n>1)
salary(1)=5000 (n=1)
很明显这是一个递归的过程,可以将该过程分为两个阶段:回溯与递推
1 回溯阶段:
要求第n个员工的薪水,需要回溯得到(n-1)个员工的薪水,以此类推,直到得到第一个员工的薪水,此时,salary(1)已知,因而不必再向前回溯了。
2 递推阶段:
从第一个员工的薪水可以推算出第二个员工的薪水(6000),从第二个员工的薪水可以推算出第三个员工的薪水(7000),以此类推,一直推算出第第四个员工的薪水(8000)为止,递归结束。
- 注意:递归一定要有一个结束条件,这里n=1就是结束条件。
代码实现:
def salary(n):
if n==1:
return 5000
return salary(n-1)+1000
s=salary(4)
print(s)
执行结果:
8000
程序分析:
在未满足n == 1的条件时,一直进行递归调用,即一直回溯 而在满足n == 1的条件时,终止递归调用,即结束回溯,从而进入递推阶段,依次推导直到得到最终的结果。
递归本质就是在做重复的事情,所以理论上递归可以解决的问题循环也都可以解决,只不过在某些情况下,使用递归会更容易实现,比如有一个嵌套多层的列表,要求打印出所有的元素,代码实现如下
items=[[1,2],3,[4,[5,[6,7]]]]
def foo(items):
for i in items:
if isinstance(i,list): #满足未遍历完items以及if判断成立的条件时,一直进行递归调用
foo(i)
else:
print(i,end=' ')
foo(items) #打印结果1 2 3 4 5 6 7
使用递归,我们只需要分析出要重复执行的代码逻辑,然后提取进入下一次递归调用的条件或者说递归结束的条件即可,代码实现起来简洁清晰