首页 > 其他分享 >递归函数

递归函数

时间:2022-11-09 14:35:24浏览次数:44  
标签:story 递归 递归函数 age 997 key 有座

楔子

在讲今天的内容之前,我们先来讲一个故事,讲的什么呢?从前有座山,山里有座庙,庙里有个老和尚讲故事,讲的什么呢?从前有座山,山里有座庙,庙里有个老和尚讲故事,讲的什么呢?从前有座山,山里有座庙,庙里有个老和尚讲故事,讲的什么呢?从前有座山,山里有座庙,庙里有个老和尚讲故事,讲的什么呢......这个故事你们不喊停我能讲一天!我们说,生活中的例子也能被写成程序,刚刚这个故事,让你们写,你们怎么写呀?

while True:
story = "
从前有个山,山里有座庙,庙里老和尚讲故事,
讲的什么呢?
"
print(story)

你肯定是要这么写的,但是,现在我们已经学了函数了,什么东西都要放到函数里去调用、执行。于是你肯定会说,我就这么写:

def story():
s = """
从前有个山,山里有座庙,庙里老和尚讲故事,
讲的什么呢?
"""
print(s)

while True:
story()

但是大家来看看,我是怎么写的!

def story():
s = """
从前有个山,山里有座庙,庙里老和尚讲故事,
讲的什么呢?
"""
print(s)
story()

story()

先不管函数最后的报错,除了报错之外,我们能看的出来,这一段代码和上面的代码执行效果是一样的。

初识递归

递归的定义——在一个函数里再调用这个函数本身

现在我们已经大概知道刚刚讲的story函数做了什么,就是在一个函数里再调用这个函数本身,这种魔性的使用函数的方式就叫做递归

刚刚我们就已经写了一个最简单的递归函数。

递归的最大深度——997

正如你们刚刚看到的,递归函数如果不受到外力的阻止会一直执行下去。但是我们之前已经说过关于函数调用的问题,每一次函数调用都会产生一个属于它自己的名称空间,如果一直调用下去,就会造成名称空间占用太多内存的问题,于是python为了杜绝此类现象,强制的将递归层数控制在了997(只要997!你买不了吃亏,买不了上当...).

拿什么来证明这个“997理论”呢?这里我们可以做一个实验:

def foo(n):
print(n)
n += 1
foo(n)
foo(1)

 

由此我们可以看出,未报错之前能看到的最大数字就是997.当然了,997是python为了我们程序的内存优化所设定的一个默认值,我们当然还可以通过一些手段去修改它:

 

import sys
print(sys.setrecursionlimit(100000))

 

我们可以通过这种方式来修改递归的最大深度,刚刚我们将python允许的递归深度设置为了10w,至于实际可以达到的深度就取决于计算机的性能了。不过我们还是不推荐修改这个默认的递归深度,因为如果用997层递归都没有解决的问题要么是不适合使用递归来解决要么是你代码写的太烂了~~~

看到这里,你可能会觉得递归也并不是多么好的东西,不如while True好用呢!然而,江湖上流传这这样一句话叫做:人理解循环,神理解递归。所以你可别小看了递归函数,很多人被拦在大神的门槛外这么多年,就是因为没能领悟递归的真谛。而且之后我们学习的很多算法都会和递归有关系。来吧,只有学会了才有资本嫌弃!

​​返回顶部​​

再谈递归

这里我们又要举个例子来说明递归能做的事情。

例一:

现在你们问我,alex老师多大了?我说我不告诉你,但alex比 egon 大两岁。

你想知道alex多大,你是不是还得去问egon?egon说,我也不告诉你,但我比武sir大两岁。

你又问武sir,武sir也不告诉你,他说他比金鑫大两岁。

那你问金鑫,金鑫告诉你,他40了。。。

这个时候你是不是就知道了?alex多大?

1

金鑫  

40

2

武sir  

42

3

egon  

44

4

alex   

46

你为什么能知道的?

首先,你是不是问alex的年龄,结果又找到egon、武sir、金鑫,你挨个儿问过去,一直到拿到一个确切的答案,然后顺着这条线再找回来,才得到最终alex的年龄。这个过程已经非常接近递归的思想。我们就来具体的我分析一下,这几个人之间的规律。

age(4) = age(3) + 2 
age(3) = age(2) + 2
age(2) = age(1) + 2
age(1) = 40

那这样的情况下,我们的函数应该怎么写呢?

def age(n):
if n == 1:
return 40
else:
return age(n-1)+2

print(age(4))

 

​​返回顶部​​

递归函数与三级菜单

menu = {
'北京': {
'海淀': {
'五道口': {
'soho': {},
'网易': {},
'google': {}
},
'中关村': {
'爱奇艺': {},
'汽车之家': {},
'youku': {},
},
'上地': {
'百度': {},
},
},
'昌平': {
'沙河': {
'老男孩': {},
'北航': {},
},
'天通苑': {},
'回龙观': {},
},
'朝阳': {},
'东城': {},
},
'上海': {
'闵行': {
"人民广场": {
'炸鸡店': {}
}
},
'闸北': {
'火车战': {
'携程': {}
}
},
'浦东': {},
},
'山东': {},
}
1 def threeLM(dic):
2 while True:
3 for k in dic:print(k)
4 key = input('input>>').strip()
5 if key == 'b' or key == 'q':return key
6 elif key in dic.keys() and dic[key]:
7 ret = threeLM(dic[key])
8 if ret == 'q': return 'q'

9
10 threeLM(menu)

还记得之前写过的三级菜单作业么?现在咱们用递归来写一下~

l = [menu]
while l:
for key in l[-1]:print(key)
k = input('input>>').strip() # 北京
if k in l[-1].keys() and l[-1][k]:l.append(l[-1][k])
elif k == 'b':l.pop()
elif k == 'q':break

 

递归函数与二分查找算法


标签:story,递归,递归函数,age,997,key,有座
From: https://blog.51cto.com/aaronthon/5836309

相关文章

  • 1-2 变量与递归函数
    变量作用域(全局变量和局部变量)变量变量起作用的范围称为变量的作用域,不同作用域内同名变量之间互不影响。变量分为:全局变量、局部变量。全局变量1.在函数和类定义之外......
  • js中递归函数
    一、什么是递归函数简单来说,递归函数就是一个函数直接或间接地调用自身,递归函数实现的基本思路1.设定好函数的功能(包括参数和返回值的设计),这是最关键的一环。......
  • 递归函数
    概念:需要满足两个条件1.引用自身 2.有一个最小可能性返回值1#n的阶乘2#方法一(常规)3deffactorial(n):4result=15foriinrange(1,n+1):......
  • 递归函数
    目录递归函数递归函数递归函数就是直接或间接调用函数自身的函数,当我们使用这种函数的时候,并不会出现预料之中的死循环,当循环次数达到1000左右就会被解释器强行停止,虽然......
  • 装饰器与递归函数
    多层语法糖"""多层语法糖加载顺序由下往上每次执行之后如果上面还有语法糖则直接将返回值函数名传给上面的语法糖如果上面没有语法糖了则变形index=outter1(wrapper......
  • 有参装饰器及递归函数
    昨日内容回顾global与nonlocal关键字global 函数体内部调用全局名称空间内的变量。nonlocal 函数嵌套后,内部函数调用外部函数名称空间内的变量。闭包函数函数嵌套......
  • 多层语法糖、有参装饰器、及递归函数
    多层语法糖、有参装饰器、及递归函数目录多层语法糖、有参装饰器、及递归函数一、多层语法糖二、有参装饰器三、装饰器模板四、装饰器修复技术五、递归函数六、昨日作业详......
  • 多层语法糖,有参装饰器,递归函数
    多层语法糖deffunc1(a1):#1定义了函数func1#14func1(foo2) print('加载了func1')#15加载了func1 deffoo1(*args,**kwargs): print('执行了foo1')......
  • 装饰器补充和递归函数
    装饰器补充和递归函数多层语法糖问题我们在写代码时可能会遇到同一个函数用多个语法糖来装饰,那么他们之间的关系是什么,怎么执行的就需要看一下下面这段代码了defoutter......
  • 多层语法糖、装饰器、递归函数
    多层语法糖、装饰器、递归函数目录多层语法糖、装饰器、递归函数一、多层语法糖二、有参装饰器三、装饰器模板1、最常用的无参装饰器2、不常用的有参装饰器四、装饰器修复......