(15)函数的地递归
什么是函数的递归
在调用一个函数的过程中又直接或者间接地调用该函数本身,称之为函数的递归调用
递归的调用是有层级限制的。默认从0 -997
递归的用处
递归的本质就是循环,某些地方比循环方便,for循环取值方便,while循环是条件循环(受条件控制),而递归也是一个重复的过程,优势只需要把控住在满足什么条件的情况下把回溯结束掉,简单来说只要把控递归的结束条件
_________________
递归调用的基本形式 #直接调用自己
def foo():
print('from foo')
foo()
这就是递归的基本形态
__________________
_________________
递归调用的基本形式 #间接调用自己
def bar():
print('from bar')
foo()
def foo():
print('from foo')
bar()
这就是递归的基本形态
__________________
函数递归必须满足两个条件:
1. 必须有一个明确的结束条件
2. 每进入下一层递归,问题的规模都应该有所减少
由上述两个条件可以推导出递归应该有两个明确的阶段:
1. 回溯: 一层一层地递归调用下去
2. 递推: 在某一层结束掉递归,开始往回一层层地返回
例:递归的概念
回溯的概念:问一个人的年龄,他说我比后面的大2岁,再次问后面的你几岁,他又说我比后面的大2岁,再去问他后面的,他说我比后面的大2岁,继续问后面告诉我18岁(拿到结果了这就是明确的结束条件)
递推:当第四个人告诉我18岁,那么我从第四个人开始往前加2岁,直到得出第一个人的年龄是24(就是往回一个一个的推结果)
这个一层一层往下调用就是回溯,满足一个结束条件后,一层一层往上返回的概念就是递推
函数递归的实例
def age(n):
if n == 1:
return 18
return age(n-1) + 2
例:把列表中所有的值取出
list1=[1,[2,[3,[4,[5,[6,[7,]]]]]]]
def func(l):
for item in l:
if type(item) is list: #如果是列表
func(item) #返回自身
else:
print(item) #不是列表则打印出来
func(list1)
PS:逻辑就是通过递归,判断如果是列表则返回自身回到函数开始层,然后进行for循环,不是列表就是打印
例:数字列表按照从小大的顺序排列
nums=[11,13,21,31,43,101,221,302,339,443]
find_num=444
for num in nums:
if num == find_num:
print('find it')
break
else:
print('not exist')
num = '1-2*((60+2*(-3-40.0/5)*(9-2*5/3+7/3*99/4*2998+10*568/14))-(-4*3)/(16-3*2))'
import re
def one(num):
'''乘除模块'''
mch = re.findall('[-+*/](\d+\.?\d*[*/]\d+\.?\d*)',num)
if not mch:
return num #如果这里没有返回值,应该是递归(自身调用自身)时候没有带返回值
for item in mch:
if '/' in item:
n1,n2 = item.split('/')
total = float(n1) / float(n2)
x = re.sub(item, str(total), num)
num = x
elif '*' in item:
n1 ,n2 = item.split('*')
total = float(n1) * float(n2)
p = str(n1)+'\*'+str(n2) #将正则得到的字符串重新拼接将特殊符号转义成普通字符
x = re.sub(p,str(total),num)
num = x
return one(num) #这里,如果直接调用自身则递归结束没有返回值,所以这里必须要return带一个返回值调用自身
print(one(num))
PS:函数递归的时候如果自己调用自己的时候没有返回值,那么后续的调用都是没有返回值的,所以如果要有返回值,每一次的递归都要有一个返回值
函数递归的图示