添加多个装饰器 函数递归 递归实现二分法,匿名函数
添加多个装饰器 函数递归 递归实现二分法,匿名函数
练习自己实现range功能
#定义自己的range
def my_range(start,stop,step): #三个参数 初始位置 结束 步长
while start<stop: #开始<结束 执行下面代码
yield start #yield返回一个生成器 自定义迭代器
start+=step #开始 +步长等于新的start
res=my_range (1,5,2) #调方法,不接收的话 输出的是内存地址
print(next(res)) # 自定义迭代器所以next方法取值
print(next(res))
# print(next(res)) #报错
1.多个装饰器执行顺序
def duco1(func1): #func1=wrapper2内存地址
def wrapper1(*args,**kwargs):
print('-----------------wrapper1') #
res1=func1(*args,**kwargs)
# print('-----------------wrapper1')
return res1
return wrapper1 #返回wrapper1内存地址
def duco2(func2): #func2=wrapper3内存地址
def wrapper2(*args,**kwargs):
print('-----------------wrapper2')
res2=func2(*args,**kwargs)
# print('-----------------wrapper2')
return res2
return wrapper2 #返回wrapper2内存地址
def duco3(func3): #func3=最原始index内存地址
def wrapper3(*args,**kwargs):
print('-----------------wrapper3')
res3=func3(*args,**kwargs)
# print('-----------------wrapper3')
return res3
return wrapper3 #返回wrapper3内存地址
#最终的地址赋值给index内存地址 index=wrapper1的内存地址
@duco1 #包括下面 所以deco1(wrapper2的内存地址)--> return返回的是wrapper1的内存地址
@duco2 #包括下面 所以deco2(wrapper3的内存地址)--> return返回的是wrapper2的内存地址
@duco3 #index=duco3(index) #deco3=(最原始的index内存地址) return返回wrapper3的内存地址
def index():
print('-----------------index')
print(index)
index()
#结论 有多个装饰器 调index 其实调的是wrapper1 ,wrapper1调的是wrapper2,wrapper2调的是wrapper3 wrapper3调index
index返回值,然后wrapper3返回交给res3,wrapper2返回交给res2,wrapper1返回交给res1
2.函数递归调用
1 什么是函数递归调用
函数递归调用是函数嵌套调用的一种特殊格式,具体是指在调用一个函数的过程
又直接或者间接地调用自己
函数递归调用不应该无限递归调用下去,应该在满足某种条件下结束递归调用
所以,函数递归应该分为两个阶段:
1、回溯 一个一个问 问到最后 一定有个结束
2、递推 往回推
2 为何要用
重复运行代码的第三种方案
3 如何用
l = [1, [2, [3, [4, [5, [6, [7, [8, [9,[111]]]]]]]]]]
def foo(dd):
for line in dd: #line等于 1, [2, [3, [4, [5, [6, [7, [8, [9,[111]]]]]]]]]
if type(line) is not list:
print(line)
else:
foo(line)
foo(l)
4递归实现二分法
l =[1,12,21,31,41,51,61,71,81,91]
def dichotomy(nums,find_nums):
print(nums)
if len(nums)==0:
print('不存在')
return
mid_nums=len(nums)//2 #求中间值索引
if find_nums>nums[mid_nums]:#要查找的数字大于中间的数字,左面的肯定不是 取右面的
dichotomy(nums[mid_nums+1:],find_nums) # 在调用这个方法,通过中间值取右面的值
elif find_nums<nums[mid_nums]:#要查找的数字小于中间的数字,右面的肯定不是 取左面的
dichotomy(nums[:mid_nums],find_nums)
else:
print('你要找的数字为:',nums[mid_nums])
dichotomy(l,41)
3.生成式
#列表生成式 把for循环和里面的if简化变成一行输出
c=[i for i in range(1,6)] #for循环 最左面的是满足执行什么 因为直接在列表所以省略append 直接添加i
print(c)
输出结果:[1, 2, 3, 4, 5]
#字典生成式
res = {k:v for k,v in [('name', 'egon'), ('age', 18)]}
res = {i:i for i in range(5)}
print(res,type(res))
输出结果{0: 0, 1: 1, 2: 2, 3: 3, 4: 4} <class 'dict'>
#集合生成式
res = {i for i in range(5)}
print(res,type(res))
输出结果{0, 1, 2, 3, 4} <class 'set'>
#生成器表达式 没有专门的元组 生成器表达式需要.next
g = (i for i in range(1,6)) #返回的是一个生成器内存地址
print(g)
print(next(g))
print(next(g))
print(next(g))
print(next(g))
print(next(g))
# print(next(g)) #报错
sum求和
4.匿名函数
没有名字的函数 执行一次就清除了
原版:
def foo(x, y):
return x + y
匿名函数:方式一 f=lambda x,y:x+y #x,y形参 满足 输出x+y 基本忽略 因为有名字
print(f(3,4)) #7
方式二
res = (lambda x,y:x+y)(1,2) #直接赋值 方法名() ,立即运行函数 调用这个方法
print(res)
匿名函数真正的用途是与其他函数配合使用
根据薪资排名,排的是人名 max求最大值
salaries = {
'赛文': 30000,
'迪迦': 5000,
'泰罗': 8000,
'特兰克斯': 2000,
'孙悟饭': 5002
}
#key 根据这个返回值排序 一般只用一次 所以用匿名函数最合适, 如果列表直接调用max就好 字典需要指定key根据返回值排序 key需要是一个方法返回值
:之前的是传进来的参数,后面是返回的值
print(max(salaries,key= lambda k:salaries[k])) #赛文 最大值
print(min(salaries,key= lambda k:salaries[k])) #特兰克斯 最小值
#排序默认从小到大
print(sorted(salaries,key= lambda k:salaries[k])) #排序 #['特兰克斯', '迪迦', '孙悟饭', '泰罗', '赛文'] 从小到大
print(sorted(salaries,key= lambda k:salaries[k],reverse=True))#['赛文', '泰罗', '孙悟饭', '迪迦', '特兰克斯'] 从大到小