递归函数 (关键点在于找到明确的函数结束点)
递归调用:在调用一个函数的过程中,直接或间接的调用了该函数的本身 而且递归函数必须要有一个结束条件
无限的递归理论上是不允许的 最大允许997层 也可以通过sys模块进行修改 但是本质递归层数与取决于电脑自身硬件内存
def func(): print('>>>func') func() func 无限递归 无限
查看最大递归层数 #面向函数编程 mport sys #python限制在997/998 ys.setrecursionlimit(10000000) #可以修改 COUNT = 0 def func(): #recursion 递归 global COUNT COUNT += 1 print(COUNT) func()
*****解耦 *****
要完成一个完整的功能,但这个功能的规模要尽量小,并且和这个功能无关的其他代码应该和这个函数分离
1.增强代码的重用性
2.减少代码变更的相互影响
什么是递归 #recursion 递归
一个函数在内部调用自己
递归的层数在python里是有限制的
递归效率低,需要在进入下一递归时保留当前的状态.
1.1必须有一个明确的结束条件
1.2每进入更深一次递归,问题规模相比上次递归都应该有所减少
l=[1,[2,3,[4,5,[6,7,[8,9,[10,11,[12,13]]]]]]] def func(l): for i in l: if isinstance(i,list): func(i) else: print(i) func(l)
递归实例一:简单年龄
敲两遍 就看懂了 我是不是快成神了 你说你不懂怎么办? 那更好办 敲20遍 还不懂? 神不需要理解凡尘 #写递归函数必须要有一个结束条件 这是先决条件 #alex #alex比egon大两岁 +2 #egon比wushi大两岁 +2 #wushi比金鑫大两岁 +2 #金鑫40了 def age(n): if n ==4: return 40 return age(n+1)+2# 关键点在于这个return 返回的值是返回给他自身调用的自己而不是返回给age() 而是返回给age()+2 #这里还有一个关键点就是 return返回自己调用自己的结果时 可以加上附加条件(就是自己想要计算的) print(age(1)) #结果为42 # def age(n): # if n==4: # return 40 # return age(n+1)+2 #递归分为两部曲(递+归) #以下是递 加归 # def age(1): # return age(2)+2 #相当于44+2=46 # # def age(2): # return age(3)+2 #相当于42+2=44 # # def age(3): # return age(4)+2 #相当于40+2=42 # # def age(4): # if 4==4: # return 40#返回给调用者上层函数
递归实例二:简单数字阶乘
递归不难就是看你肯不肯去倒腾了 #求阶乘 n = 7 7*6*5*4*3*2*1 def func(n): if n == 1: return 1 else: return n*func(n-1) ret = func(4) print(ret) # #n = 4 # def func(4): # return 4*(4-1) n=3 2*(4-1)*4=24 # # #n = 3 # def func(3): # return 3*(3-1) n=2 1*(3-1) # # #n = 2 # def func(2): # return 2 2*(2-1) n=1 1*(2-1) # # #n = 1 # def func(n): # if n == 1: # return 1
二分查找方法(普通版)
l = [2,3,5,10,15,16,18,22,26,30,32,35,41,42,43,55,56,66,67,69,72,76,82,83,88] def func(l,aim): mid = (len(l)-1)//2 if l: if aim > l[mid]: func(l[mid+1:],aim) elif aim < l[mid]: func(l[:mid],aim) elif aim == l[mid]: print("bingo",mid) else: print('找不到') func(l,66) func(l,6)
# list.sort()将列表进行有序化排列 # def search(num ,l ,start=None,end=None): #定义函数()内写 要找寻的数字,数字所在的列表,开始查找的数字,查找结束的数字 # start=start if start else 0 # end = end if end else len(l)-1 # mid = (end-start)//2+start #默认开始值是0 结束值列表索引最后一位 中间值为末尾减去开始得的值除以2 加上开始的值 # if l[mid]>num: # search(num,l,start,mid-1) # elif l[mid]<num: # search(num,l,mid+1,end) # elif l[mid]==num: # print(mid,l[mid]) #判断阶段分为3种 大于小于 等于 每一次的判断 找寻的数字 和列表不变 但是开始查找的数字和结束的数字会根据判断条件改变 # 直到找到查找的值 # l=[2,3,5,10,15,16,18,22,26,30,32,35,41,42,43,55,56,66,67,69,72,76,82,83,88] # search(66,l) def search(num,l,start=None,end=None): #66,[2,3,5,10,15,16,18,22,26,30,32,35,41,42,43,55,56,66,67,69,72,76,82,83,88] start = start if start else 0 #start = 0 end = end if end else len(l) - 1 #end = 24 mid = (end - start)//2 + start #mid = 12 if l[mid] > num : #l[mid] = 41 < 66 search(num,l,start,mid-1) elif l[mid] < num: ret = search(num,l,mid+1,end) #search(66,l,13,24) return ret elif l[mid] == num: return mid, l[mid] def search(num,l,start=None,end=None): #66,[2,3,5,10,15,16,18,22,26,30,32,35,41,42,43,55,56,66,67,69,72,76,82,83,88] start = start if start else 0 #start = 13 end = end if end else len(l) - 1 #end = 24 mid = (end - start)//2 + start #mid = 18 if l[mid] > num : #l[mid] = 67 > 66 search(num,l,start,mid-1) #search(66,l,13,17) elif l[mid] < num: ret = search(num,l,mid+1,end) return ret elif l[mid] == num: return mid, l[mid] def search(num,l,start=None,end=None): #66,[2,3,5,10,15,16,18,22,26,30,32,35,41,42,43,55,56,66,67,69,72,76,82,83,88] start = start if start else 0 #start = 13 end = end if end else len(l) - 1 #end = 17 mid = (end - start)//2 + start #mid = 15 if l[mid] > num : #l[mid] = 56 < 66 search(num,l,start,mid-1) elif l[mid] < num: ret = search(num,l,mid+1,end) #search(66,l,16,17) return ret elif l[mid] == num: return mid, l[mid] def search(num,l,start=None,end=None): #66,[2,3,5,10,15,16,18,22,26,30,32,35,41,42,43,55,56,66,67,69,72,76,82,83,88] start = start if start else 0 #start = 16 end = end if end else len(l) - 1 #end = 17 mid = (end - start)//2 + start #mid = 16 if l[mid] > num : #l[mid] = 56 < 66 search(num,l,start,mid-1) elif l[mid] < num: ret = search(num,l,mid+1,end) #search(66,l,17,17) return ret elif l[mid] == num: return mid, l[mid] def search(num,l,start=None,end=None): #66,[2,3,5,10,15,16,18,22,26,30,32,35,41,42,43,55,56,66,67,69,72,76,82,83,88] start = start if start else 0 #start = 17 end = end if end else len(l) - 1 #end = 17 mid = (end - start)//2 + start #mid = 17 if l[mid] > num : #l[mid] = 66 == 66 search(num,l,start,mid-1) elif l[mid] < num: search(num,l,mid+1,end) elif l[mid] == num: return mid, l[mid] #return 17,66
二分查找方法(升级版)
def func(l, aim,start = 0,end = len(l)-1 ): mid = (start+end)//2 if not l[start:end+1]: return elif aim > l[mid]: return func(l,aim,mid+1,end) elif aim < l[mid]: return func(l,aim,start,mid-1) elif aim == l[mid]: print("bingo") return mid index = func(l,68) print(index)
递归编写三级菜单
menu = { '北京': { '海淀': { '五道口': { 'soho': {}, '网易': {}, 'google': {} }, '中关村': { '爱奇艺': {}, '汽车之家': {}, 'youku': {}, }, '上地': { '百度': {}, }, }, '昌平': { '沙河': { '老男孩': {}, '北航': {}, }, '天通苑': {}, '回龙观': {}, }, '朝阳': {}, '东城': {}, }, '上海': { '闵行': { "人民广场": { '炸鸡店': {} } }, '闸北': { '火车战': { '携程': {} } }, '浦东': {}, }, '山东': {}, } def threeLM(menu): while True: for key in menu: print(key) k = input(">>>") if k in menu: threeLM(menu[k]) threeLM(menu)
menu = { '北京': { '海淀': { '五道口': { 'soho': {}, '网易': {}, 'google': {} }, '中关村': { '爱奇艺': {}, '汽车之家': {}, 'youku': {}, }, '上地': { '百度': {}, }, }, '昌平': { '沙河': { '老男孩': {}, '北航': {}, }, '天通苑': {}, '回龙观': {}, }, '朝阳': {}, '东城': {}, }, '上海': { '闵行': { "人民广场": { '炸鸡店': {} } }, '闸北': { '火车战': { '携程': {} } }, '浦东': {}, }, '山东': {}, } #相同的数据类型 嵌套在一起 # def Three_Level_Menu(menu): # while True: # for k in menu:print(k) # key = input('>>>') # if key == 'q':return 'q' # elif key == 'b':break # elif key in menu: # ret = Three_Level_Menu(menu[key]) # if ret == 'q': return 'q' # Three_Level_Menu(menu)