递归函数
递归的定义——在一个函数里再调用这个函数本身
递归的最大深度——997
递归函数如果不受外力的阻止就会一直执行下去,但每一次函数调用都会产生一个属于它自己的名称空间,如果一直调用下去,就会造成名称空间占用太多内存的问题,于是python为了杜绝此类现象,强制的将递归层数控制在了997
def foo(n): print(n) n += 1 foo(n) foo(1)
Of course,997是python为了我们程序的内存优化所设定的一个默认值,我们还是可以通过一些方式修改默认值的
import sys print(sys.setrecursionlimit(100000))
不过不推荐修改默认递归深度,因为如果用997层递归都没有解决的问题不是代码太烂那就是不适合使用递归来解决
递归示例
我们想知道alex多大了?现只知道alex比 egon 大两岁。
你想知道alex多大,你是不是还得去问egon?egon说,我不告诉你,但我比武sir大两岁。
你又问武sir,武sir也不告诉你,他说他比金鑫大两岁。
那你问金鑫,金鑫告诉你,他40了。。。
这个时候你是不是就知道了?alex多大?
def age(n): if n == 4: return 40 return age(n+1)+2 print(age(1)) # 46
二分查找算法
定义:二分查找又称折半查找
优点:比较次数少,查找速度快,平均性能好
缺点:要求待查表为有序表,且执行插入删除操作困难
因此,折半查找方法适用于不经常变动而查找频繁的有序列表。首先,假设列表中元素是按升序排列,将列表中间位置记录的值与所需查找的值比较,如果两者相等,则查找成功;否则利用中间位置记录将列表分成前、后两个子表,如果中间位置记录的值大于需要查找的值,则进一步查找前一子表,否则进一步查找后一子表。重复以上过程,直到找到满足条件的记录,查找成功,或直到子表不存在为止,此时查找不成功
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)
def find_2(l,aim,start=0,end=None): if end == None:end = len(l) - 1 if start <= end: mid = (end-start) // 2 + start if l[mid] > aim: find_2(l,aim,start,mid-1) elif l[mid] < aim: find_2(l,aim,mid+1,end) else: print(aim,mid) else: print('找不到这个值') 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] find_2(l,32) # 32 10
阶乘
def f(n): if n==1: return 1 return n*f(n-1) print(f(3)) # 6
斐波那契数列
def fib(n): if n==1 or n==2: return 1 return fib(n-1)+fib(n-2) print(fib(8)) # 21
三级菜单
menu = { '北京': { '海淀': { '五道口': { 'soho': {}, '网易': {}, 'google': {} }, '中关村': { '爱奇艺': {}, '汽车之家': {}, 'youku': {}, }, '上地': { '百度': {}, }, }, '昌平': { '沙河': { '老男孩': {}, '北航': {}, }, '天通苑': {}, '回龙观': {}, }, '朝阳': {}, '东城': {}, }, '上海': { '闵行': { "人民广场": { '炸鸡店': {} } }, '闸北': { '火车战': { '携程': {} } }, '浦东': {}, }, '山东': {}, } def menu_3(menu): while True: for key in menu: print(key) choice=input('选择:') if choice == 'q' or choice == 'b': return choice elif choice in menu and menu_3(menu[choice]): borq = menu_3(menu[choice]) if borq == 'q': return 'q' menu_3(menu)
装饰器函数
装饰器的本质——一个闭包函数
装饰器的功能——在不修改原函数本身及其调用方式的前提下在原函数前后添加功能
def timer(func): def inner(*args,**kwargs): '''执行函数之前要做的''' re = func(*args,**kwargs) '''执行函数之后要做的''' return re return inner
from functools import wraps def deco(func): @wraps(func) #加在最内层函数正上方 def wrapper(*args,**kwargs): return func(*args,**kwargs) return wrapper
开放封闭原则
对扩展是开放的
任何一个程序,不可能在设计之初就已经想好了所有的功能并且未来不做任何关心和修改,所以必须允许代码扩展、添加新功能
对修改是封闭的
我们所写的程序都是要交给用户使用的,如果我们随意对其进行修改,很有可能影响已经在使用程序的用户
装饰器完美的遵循了这个开放封闭原则
装饰器的形成过程
import time def func1(): print('in func1') def timer(func): def inner(): start = time.time() func() print(time.time() - start) return inner func1 = timer(func1) func1()
为了省略上面那一次赋值调用,python为我们提供了一句语法糖来解决这个问题
import time def timer(func): def inner(): start = time.time() func() print(time.time() - start) return inner @timer #==> func1 = timer(func1) def func1(): print('in func1') func1()
def timer(func): def inner(a): start = time.time() func(a) print(time.time() - start) return inner @timer def func1(a): print(a) func1(1)
import time def timer(func): def inner(*args,**kwargs): start = time.time() re = func(*args,**kwargs) print(time.time() - start) return re return inner @timer #==> func1 = timer(func1) def func1(a,b): print('in func1') @timer #==> func2 = timer(func2) def func2(a): print('in func2 and get a:%s'%(a)) return 'fun2 over' func1('aaaaaa','bbbbbb') print(func2('aaaaaa'))
import time def timer(func): def inner(*args,**kwargs): start = time.time() re = func(*args,**kwargs) print(time.time() - start) return re return inner @timer #==> func2 = timer(func2) def func2(a): print('in func2 and get a:%s'%(a)) return 'fun2 over' func2('aaaaaa','bbbbbb') print(func2('aaaaaa'))
正常情况下一些查看函数信息的方法都会在装饰器这里失效
def index(): '''这是一个主页信息''' print('from index') print(index.__doc__) #查看函数注释的方法 print(index.__name__) #查看函数名的方法
为了不让它们失效,需要在装饰器上加上一点来完善
from functools import wraps def deco(func): @wraps(func) #加在最内层函数正上方 def wrapper(*args,**kwargs): return func(*args,**kwargs) return wrapper @deco def index(): '''哈哈哈哈''' print('from index') print(index.__doc__) print(index.__name__)
多个装饰器装饰同一个函数
def wrapper1(func): def inner(): print('wrapper1 ,before func') func() print('wrapper1 ,after func') return inner def wrapper2(func): def inner(): print('wrapper2 ,before func') func() print('wrapper2 ,after func') return inner @wrapper2 @wrapper1 def f(): print('in f') f()