高阶函数
-
函数就是变量
python中定义函数就是定义类型是function的变量,函数名就是变量名
变量能做的,函数名也能做
面试题
list1=[]
for i in range(5):
list1.append(lambda x:x*i)
"""
i=0:[lambda x:x*i]
i=1:[lambda x:x*i], [lambda x:x*i]
i=2:[lambda x:x*i], [lambda x:x*i], [lambda x:x*i]
i=3:[lambda x:x*i], [lambda x:x*i], [lambda x:x*i], [lambda x:x*i]
i=4:[lambda x:x*i], [lambda x:x*i], [lambda x:x*i], [lambda x:x*i], [lambda x:x*i]
lambda x:x*i
"""
print(list1[1](2)) # 8
print(list1[2](2)) # 8
实参高阶函数
-
实参高阶函数
参数是函数的函数就是实参高阶函数
def func1(x): print(x()) def func2(m=10): print('你好!') func1(func2)
-
系统常见实参高阶函数的使用
max、min、sorted、map、reduce
- max、min
-
max(序列) - 比较序列中元素的大小来获取值最大的元素
-
max(序列, key=函数) - 函数决定求最大值的时候的比较对象
参数key的要求:a.是一个函数 b. 这个函数有且只有一个参数(这个参数指向的就是序列中的元素) c.函数要有一个返回值(比较对象)
-
求列表中个位数最大的元素
nums = [19, 38, 40, 27, 53, 72] # def f1(item): # return item % 10 # result = max(nums, key=f1) print(max(nums, key=lambda item: item % 10))
-
求所有学生中成绩最高的学生
students = [ {'name': 'stu1', 'age': 18, 'score': 90}, {'name': 'stu2', 'age': 19, 'score': 78}, {'name': 'stu3', 'age': 20, 'score': 83}, {'name': 'stu4', 'age': 21, 'score': 94} ] def f2(item): return item['score'] print(max(students, key=f2))
-
练习:获取列表中数字各位数的和的最大元素
nums = [23, 78, 90, 73, 233, 91] # def f3(item): # n = [int(x) for x in str(item)] # return sum(n) # # print(max(nums,key=f3)) print(max(nums, key=lambda item: sum([int(x) for x in str(item)])))
-
sorted
sorted(序列) - 比较序列中元素的大小对序列中元素从小到大排序
sorted(序列, key=函数) - 函数决定排序的时候比较大小的比较对象
函数要求:a.是一个函数 b.需要一个参数(指向序列中的元素) c.需要一个返回值(比较对象)
-
-
练习1:让列表中的元素按照个位数的大小从小到大排序
nums = [19, 38, 40, 27, 53, 72] def f4(item): return item % 10 print(sorted(nums, key=f4))
-
练习2:将students按照学生的年龄从大到小排序
students = [ {'name': 'stu1', 'age': 18, 'score': 90}, {'name': 'stu2', 'age': 19, 'score': 78}, {'name': 'stu3', 'age': 20, 'score': 83}, {'name': 'stu4', 'age': 21, 'score': 94} ] def f5(item): return item['age'] print(sorted(students, key=f5, reverse=True))
-
map
用法一:原序列 -> 新序列
map(函数, 序列) - 将序列按照指定的方式进行转换,返回值是一个map对象(map对象是序列)
函数的要求:a.有一个参数(指向原序列中的元素) b.需要一个返回值(新序列中的元素)
用法一:
nums = [19, 38, 40, 27, 53, 72] result = map(lambda item: item % 10, nums) print(list(result))
用法二:
names = ['张三', '李四', '小明', '小花'] ages = [19, 29, 30, 17] result = map(lambda item1, item2: {'name': item1, 'age': item2}, names, ages) print(list(result))
-
-
练习:
c = [90, 89, 88, 99, 27, 76, 56] e = [98, 78, 66, 82, 90, 12, 78] m = [23, 98, 100, 72, 69, 27, 96] result = map(lambda item1, item2, item3: item1 + item2 + item3, c, e, m) print(list(result))
-
reduce
reduce(函数, 序列, 初始值)
函数的要求:a. 需要两个参数:
第一个参数 - 第一次指向初始值;从第二次开始指向上一次的运算结果
第二个参数 - 指向序列中的每一个元素
b.需要一个返回值(决定运算规则)
累计求和
from functools import reduce nums = [10, 89, 78, 20] # result = reduce(lambda x, item: x+item, nums, 0) def f1(x, item): print(f'x:{x}, item:{item}') return x+item result = reduce(f1, nums, 0) print(result)
累计求乘积
from functools import reduce nums = [8, 9, 5, 2] result = reduce(lambda s, item:s*item, nums, 1) print(result)
将一个列表里的数字拼接在一起
# [10, 89, 78, 20] -> 10897820 from functools import reduce nums = [10, 89, 78, 20] result = reduce(lambda s, item:s+str(item), nums, '') print(result)
-
无参装饰器
-
什么是装饰器
作用:装饰器是用来给函数添加功能
本质:就是一个函数(实参高阶函数+返回值高阶函数+糖语法)
用法(套路):
def 函数名1(参数1):
def 函数名2(*args, **kwargs):
新增功能的代码
原函数的返回值 = 调用原函数的代码:参数1(*args, **kwargs)
return 原函数的返回值
return 函数名2
说明:
- 函数名1 - 装饰器的名称,根据新增的功能来命名
- 参数1 - 需要添加功能的函数(原函数), 一般命名成f、fn
- 函数名2 - 添加完功能的新函数的函数名,new_f、new_fn
-
给函数添加统计函数执行时间的功能
方法一:给需要添加功能的函数添加新增功能的代码
存在的问题:如果给不同的函数添加相同的功能,相同的功能的代码要写多遍
import time def func1(): start = time.time() print('函数1的功能') end = time.time() print(f'执行时间:{end-start}') def func2(x, y): print(x+y) func1() func2(10, 20)
方法二:将需要添加的功能封装到一个函数中
存在的问题:原函数并没有新增功能
import time def func3(): print('hello world!') def func4(): print('你好,世界!') def count_time(f): # 获取开始时间 start = time.time() # 调用原函数 # func3() f() # 获取结束时间 end = time.time() # 计算时间差 print(f'执行时间:{end-start}') count_time(func3) count_time(func4)
方法三:装饰器
import time def count_time(f): def new_f(*args, **kwargs): start = time.time() f(*args, **kwargs) end = time.time() print(f'执行时间:{end-start}') return new_f print('====================================') @count_time def func5(): print('你好,python') func5()
-
练习:写一个装饰器,在函数开始执行的时候打印start
def strat(f): def new_f(*args, **kwargs): print('start') re = f(*args, **kwargs) return re return new_f @strat def func11(): print('hello world!') @strat def func22(a, b): return a*b func11() print(func22(2, 9))