Day 13 : 函数递归,

从前有有座山,山里有座庙,庙里有个老和尚给小和尚们讲故事,讲的什么呀,讲的是,从前有有座山,山里有座庙,庙里有个老和尚给小和尚们讲故事,讲的什么呀?讲的是?......

递归:1、一个函数再内部调用了自己,这种写法就叫递归( recursion)。

   2、递归额层数 在pytohn 里是有限制

   3、写递归函数必须要有一个结束条件

例1:求阶乘 n= 7   7*6*5*4*3*2*1

 

 1 def func(n):
 2     if n == 1:
 3         return 1
 4     return n*func(n-1)
 5 
 6 print(func(4))
 7 
 8 #分解步骤
 9 n = 4
10 def func(4):#4*6 = 24 func(3)*4 
11     if 4 == 1:
12         return 1
13     return 4*func(3)#当N=4时,if 条件不成立,先执行了func(3)然后进入下一步了递的过程
14 n = 3
15 def func(3):
16     if 4 == 1:
17         return 1
18     return 3*func(2)#当N=3时,if 条件不成立,先执行了func(2)然后进入下一步了以此类推
19 #下面说了。fun(2) =2 又到上一部 3*2=6
20 n = 2
21 def func(2):
22     if 2 == 1:
23         return 1
24     return 2*func(1) #2*1 =2   又回归到上一步
25 n = 1
26 def func(1):
27     if 1 == 1:
28         return 1#当N=1时,妇fun(1) =1  又执行回归的过程

 

例2  用递归函数,找索引 lis = [2,3,4,6,7,9,12,16,19,21,25,35,43,57,66,84,88,92,94,99]

 1 # lis = [2,3,4,6,7,9,12,16,19,21,25,35,43,57,66,84,88,92,94,99]
 2 #print(lis.index(57))13
 3 # index = 0
 4 # for i in lis:
 5 #     if i == 57:
 6 #         print(index)
 7 #     index += 1
 8 #这种找法太慢,如果序列有100W个数字呢?
 9 #所有使用2分算法 每次把列表分成一半来找
10 #思路1
11 # def search(num,lis):
12 # #先找中间的数字
13 #     mid = len(lis)//2 #整除
14 #     if lis[mid] > num :#如果中间的值大于要找的值
15 #         lis = lis[0:mid]#那就从前面找值
16 #         search(num,lis)#再去前面值得中间值因为lis已经改变
17 #     elif lis[mid] <num :#如果中间的值小于要找的值
18 #         lis = lis[mid+1:]#从后面找
19 #         search(num,lis)#去后面值得中间值因为lis已经改变
20 #     elif lis[mid] == num:
21 #         return lis[mid]
22 #这个程序是错误的,因为你找的时候列表变小了。不是原来的列表了
23 #思路2
24 #你不能改变列表,你要改变索引的位置
25 lis = [2,3,4,6,7,9,12,16,19,21,25,35,43,57,66,84,88,92,94,99]
26 def search(num,lis,start = None,end=None):
27     start = start if start else  0#如果start没值使用0,有值使用传的值
28     end = end if end else len(lis)-1#如果end没值就计算,有值使用传的值
29 #先找中间的数字
30     mid = (end - start)//2 + start
31 #mid = (end-start) //2 这样不对,如果索引缩小后,值就不正确必须加前面的数字
32     if lis[mid] > num :#如果中间的值大于要找的值从左开始,
33         return search(num,lis,start,mid-1)#修改索引的位置从做开始从中间-1结束
34     elif lis[mid] < num :#如果中间的值小于要找的值从右开始,
35         return search(num,lis,mid+1,end)#中间开始,最后结束
36     elif lis[mid] == num:
37         return mid,lis[mid]
38 print(search(57,lis))
39 #此函数只有递的过程没有归的过程
递归

 例3 三级菜单实例

 1 #三级菜单
 2 menu = {'北京':{
 3     '海淀':{
 4 '永定路':{},
 5 '香山街':{}
 6     },
 7     '朝阳区':{
 8 '小红门':{},
 9 '太阳宫':{},
10 '潘家园':{}
11     }
12 }
13 ,'陕西':{
14         '西安':{
15         '临潼区':{
16             '兵马俑':{}
17         },
18             '碑林区':{
19                 '大雁塔':{}
20             }
21      },
22         '宝鸡':{
23             '凤翔县':{
24 '长青镇':{}
25             },
26             '岐山县':{
27 '某某镇':{}
28             }
29         }
30     }
31 ,'甘肃':{'兰州':{
32 '安宁区':{
33     '黄河':{}
34 },
35 '城关区':{
36     '乌金峡':{}
37 }
38     },
39        '天水':{
40 '秦州区':{
41     '县家路':{}
42 },
43 '麦积区':{
44     '麦积山':{}
45 }
46        }
47 
48     }}
49 def Three_Level_Menu(menu):
50     while True:#如果输入的菜单不存在,就让用户一直输入。
51         for name in menu:print(name)#显示第一级菜单
52         key = input('请输入名称,如果退出请输入‘Q/q,如果返回上一层请输入B/b',)
53         if key.lower() == 'b':break#只跳出了当前函数的循环,
54         elif key.lower() == 'q':#和 ret相互结合,直接退出整个函数()
55             return 'q'
56         elif key in menu:
57         # for key1 in menu[key]:print(key1)# 打印2级菜单
58         # key2 = input('请输入名称')
59 #有没有发现上面2行代码,和函数定义的第一行和第二行基本差不多一样?
60 #相同的数据类型嵌套在一起,是不是感觉可以用递归呢?是不是感觉进入一个轮回?
61 #那我们继续调用这个函数即可
62             ret = Three_Level_Menu(menu[key])#不能继续传入menu了,不然和原来的菜单一样了
63             if ret == 'q': return 'q'
64 Three_Level_Menu(menu)
三级菜单

 

posted on 2019-05-28 15:23  超nmmmmm  阅读(141)  评论(0编辑  收藏  举报

导航