递归函数
一、定义
在函数内部调用自己的函数
二、示例
1.如果没有结束条件地调用自己,就会浪费内存,超过之后就会RecursionError报错(递归报错)
def deff(): print("cc") deff() deff() #RecursionError: maximum recursion depth exceeded while calling a Python object
默认递归最大深度(997),但是最大递归深度可以修改。
import sys sys.setrecursionlimit(2000) a=0 def deff(): global a a=a+1 print(a) deff() deff() #1996 #如果不设置就是996/997
#如果递归次数太多就不建议使用递归,非常占内存
#优点是可以优化代码,更简洁
2.一个编程示例,不能直接得到答案,通过另外的结果来求解,并且两个求解方式是相同的
求4的阶乘(4!)的值。(return很重要)如果第二个不写rerurn,就会返回none
def deff2(n): global s s=n*s n=n-1
if n==1: return s #保证可以出去递归 else: return deff2(n) #保证下一层递归执行,并且有返回值 s=1 se=deff2(4) print(se)
三、算法
二分查找算法(必须处理有序的列表)
#减小工作量,如果是连续的、有序的值,找到想要的数
1.v1.0
l=[1,2,3,4,5,6,7,8,9,11,12,13,14,15,16,17,18,19,44,45,46,47,48,49,55,57,59,66] def findnum(l,aim): mid_index=len(l)//2 #整除,得到一个整数 if l[mid_index] <aim: new_l=l[mid_index+1:] findnum(new_l,aim) elif l[mid_index ]>aim: new_l=l[:mid_index] #本身在前 findnum(new_l,aim) else: print("aim ",mid_index,l[mid_index]) findnum(l,18) #此时下标不准 aim 1 18
2.v2.0
l=[1,2,3,4,5,6,7,8,9,11,12,13,14,15,16,17,18,19,44,45,46,47,48,49,55,57,59,66] def findnum(l,aim,start=0,end=len(l)): mid_index=(end-start)//2+start #从start开始往后加 if l[mid_index] <aim: findnum(l,aim,start=mid_index+1,end=end) elif l[mid_index ]>aim: findnum(l,aim,start=start,end=mid_index-1) #没有切片,应该-1 else: print("aim ",mid_index,l[mid_index]) findnum(l,7) print(l.index(7)) #一个效果 #此时假如找不到,就会报错
3.v3.0
l=[1,2,3,4,5,6,7,8,9,11,12,13,14,15,16,17,18,19,44,45,46,47,48,49,55,57,59,66] def findnum(l,aim,start=0,end=None): #不能提前预知会传给什么参数,让定义l可以在函数后面 end=len(l)if end is None else end #如果是传入了就传入,如果没传入就有默认的None mid_index=(end-start)//2+start #从start开始往后加,//向下取整 if start<=end: if l[mid_index] <aim: findnum(l,aim,start=mid_index+1,end=end) elif l[mid_index ]>aim: findnum(l,aim,start=start,end=mid_index-1) #没有切片,应该-1 else: print("aim ",mid_index,l[mid_index]) #层层返回,这里不能返回,否则返回None else: print("找不到 %s这个值"%aim) findnum(l,12) #此时差不多了,但是返回的问题不清楚
4.v4.0
l=[1,2,3,4,5,6,7,8,9,11,12,13,14,15,16,17,18,19,44,45,46,47,48,49,55,57,59,66] def findnum(l,aim,start=0,end=None): #不能提前预知会传给什么参数,让定义l可以在函数后面 end=len(l)if end is None else end #如果是传入了就传入,如果没传入就有默认的None mid_index=(end-start)//2+start #从start开始往后加,//向下取整 if start<=end: if l[mid_index] <aim: return findnum(l,aim,start=mid_index+1,end=end) elif l[mid_index ]>aim: return findnum(l,aim,start=start,end=mid_index-1) #没有切片,应该-1 else: return mid_index #要返回就全部都要返回 else: return "找不到 %s这个值"%aim print(findnum(l,20)) #完美