高阶函数
2020-07-02 本文已影响0人
大象信步走来
函数名就是变量名
- python定义函数其实就是定义一个类型是function的变量,函数名就是变量名。
- 函数也是数据类型,只支持一种操作,调用
def func1():
print('函数')
a = 10
print(type(a)) # <class 'int'>
print(type(b)) # <class 'function'>
b = a
print(b+20)
c = func1
c()
a = 100
func1 = 'abc'
高阶函数
实参高阶函数
- 被赋值变量可以作为函数的实参
- 参数是函数的函数就是实参高阶函数
# 实参高阶函数
def func3(x):
print(x(1,2))
func(lambda m,n:m+n)
系统提供的实参高阶函数
- max/min/sorted 都是实参高阶函数,
- 参数key的要求:
- 参数key是一个函数;被传入的函数需要一个参数和一个返回值,
- 这个参数指向序列中的元素,
- 返回值是比较对象
# 实例1
# 实例2
# 练习1 获取学生列表中成绩最高的学生
student2 = [
{'name': '张三', 'age': 18, 'score': 89},
{'name': '小明', 'age': 29, 'score': 60},
{'name': '李四', 'age': 25, 'score': 90},
{'name': 'Tom', 'age': 19, 'score': 87}
]
def func1(item):
return item['score']
print(max(student2,key=func1))
print(max(student2,key= lambda item:item['score']))
print(min(student2,key= lambda item:item['age']))
print(sorted(student2,key= lambda item:item['age']))
-
map 映射函数 map(函数,序列)将序列中所有的元素按照函数指定的规则生成新的元素保存在map对象中
-
函数的要求:需要一个参数和返回值,
参数指向的是序列中的元素
,返回值就是用来替换原来元素的新元素
-
应用技巧:有时需要对列表中每个元素做一个相同的处理,得到新列表
例如:所有数据乘以3
所有字符串转换为整数
两个列表对应值相加
map(func, list1, list2….)
函数func有几个参数,后面跟几个列表
# 示例1:将列表list3中所有的元素都加1 -->
map(lambda item:item+1,list3 )
# 示例2: 将列表list3中的所有元素都转换成对应的字符串:['10','20','30']
map(lambda item:str(item),list1)
# 更好的写法
map(str,list1) # 直接使用写好的函数
list(map())
- reduce(函数,序列,初始值=None)对序列中的元素按照函数提供的功能进行累计的操作
- 函数需要两个参数指向前两个元素,需要一个返回值
- 第一个参数是初始值或上次运算的结果
- 注意:如果没有给初始值,函数中的第一个参数第一次取得是序列中的第一个元素,后面每次取到的是上次运行的结果
from functools import reduce
list3 = [10,20,30,40]
# 示例1:求所有元素的和
print(reduce(lambda x,y:x+y,list3))
# 示例2:求所有元素的乘积
print(reduce(lambda x,y:x*y,list3)) #初始值有默认值,用默认值,没有默认值取第一个元素
# 示例3:求班级所有学生的总成绩
student2 = [
{'name': '张三', 'age': 18, 'score': 89},
{'name': '小明', 'age': 29, 'score': 60},
{'name': '李四', 'age': 25, 'score': 90},
{'name': 'Tom', 'age': 19, 'score': 87}
]
print(reduce(lambda x,y:x+y['score'],student2)) # TypeError: unsupported operand type(s) for +: 'dict' and 'int'
print(reduce(lambda x,y:x+y['score'],student2,0))
#上面实例中没有默认值 x取none ..
返回值高阶函数
- 返回值是函数的函数
def func1():
def func2(x,y):
return x+y
return func2
print(func1()(100,200))
装饰器
- 装饰器的作用:在不修改函数的情况下,给函数添加新的功能
- 装饰器的本质就是一个函数,它既是实参高阶函数,也是返回值高阶函数
- 装饰器在批量处理函数
无参装饰器
`def 函数名1(函数名2):
def 函数名3(agrs,*kwagrs):
新功能代码
返回值 = 函数名2(args,*kwargs)
return 函数名3`
函数名1 - 装饰器名字,命名的时候和这个装饰器要添加的功能进行关联
函数名2 - 随便命名,指向被添加功能的函数;可以命名成 fn
函数名3 - 随便命名,在原函数上添加完新的功能以后产生新的函数
新功能代码 - 实现新加的功能的代码
定义函数的时候args,*kwargs同时存在的意义不定长参数在调用的时候既可以使用位置参数也可以使用关键字参数
# 在函数开始执行前打印'函数开始'
# 练习1 返回值是字符串的函数,返回值中所有的小写字母全部变成大写字母
迭代器(iter)
什么是迭代器
- 迭代器是容器数据类型,只通过类型转换和生成器来获取迭代对象
迭代器存储数据的特点
- 同时可以保存多个数据,没有办法直接查看,而是需要先将数据从迭代器中取出来(取出之后不能放回去)
所有容器都可以转换成迭代器
iter([1,23,44])
获取迭代器中的元素
- 无论通过什么方式,只要将迭代器中的某个元素拿到了,那么这个元素在迭代器中不存在了。
# 遍历
iter5 = iter('hello')
for x in iter5:
print(f'x:{x}')
# 获取单个元素
next(迭代器对象) - 获取迭代器中的一个元素(最上面的元素)
另一种写法:迭代器对象.__next__
item6 = iter({'name':'张三','age':18})
print(next(iter3)) # name
print(next(iter3)) # age
# print(next(iter3)) # StopIteration
生成器
- 生成器就是迭代器,迭代器不一定是生成器
- 调用一个带有yield的关键字的函数就可以得到一个生成器
生成器中的元素怎么产生的
-
产生数据的机器,你需要一个数据就给你一个数据
-
生成器能生产多少数据看执行生成器对应的函数的函数体会遇到几次yield.
-
yield后面表达式的值就是生成器能够产生的数据
# 示例1:创建一个生成器可以产生3个数分别是:10,100,78
def create_gender1():
yield 10
yield 100
yield 1000
gen2 = create_gender1()
print(next(gen2))
生成器产生数据的原理
- 当获取生成器元素的时候会自动调用生成器关联的函数
- 第一次是从函数开始的地方开始执行直到遇到yield为止,并且将yield后面的值作为为获取到的数据
- 后面每次都是上一次结束为止开始执行,直到遇到yield。
- 如果全程没有遇到yield,就不会产生数据。next(生成器)会报错
生成式
列表推导式[]变成()就变成了生成式