Day11-高阶函数和装饰器
01-实参高阶函数
参数是函数的函数就是实参高阶函数
max和min的用法
-
普通用法:不做过多讲述
-
实参高阶函数
max(序列,key=函数) - 通过函数来定制求最大值的方式
序列 - 需要获取某种最大值对应的序列
函数 - 有且只有一个参数(指向/代表序列中每个元素);有一个返回值(比较的 对象)
# 求个位最大的元素 nums = [13, 32, 45, 12, 54, 67, 77, 78, 562] print(max(nums,key=lambda item:item % 10)) # 求各位数加起来最大的元素 def sum1(x): str1 = str(x) num =0 for i in str1: num += int(i) return num result = max(nums, key=sum1) print(result) # 方法二: result = max(nums, key=lambda item: sum([int(x) for x in str(item)])) print(result) # 练习:已知以下列表: students = [ {'name': 'stu1', 'age': 20, 'score': 67, 'sex': '男'}, {'name': 'stu2', 'age': 18, 'score': 82, 'sex': '女'}, {'name': 'stu3', 'age': 19, 'score': 54, 'sex': '女'}, {'name': 'stu4', 'age': 22, 'score': 77, 'sex': '男'}, {'name': 'stu5', 'age': 21, 'score': 56, 'sex': '男'}, {'name': 'stu6', 'age': 18, 'score': 78, 'sex': '男'}, {'name': 'stu7', 'age': 16, 'score': 100, 'sex': '女'} ] # 1求列表中年龄最大的学生信息 result = max(students, key=lambda item: item['age']) print(result) # 2求列表中成绩最低的学生信息 result = min(students, key=lambda item: item['score']) print(result) # 3求女生中年龄最大的学生信息 result = max([x for x in students if x['sex'] == '女'], key=lambda item: item['age']) print(result) # 4求男生中年龄最小的学生信息 result = min([x for x in students if x['sex'] == '男'], key=lambda item: item['age']) print(result)
sorted的用法
-
普通用法:sorted(序列)
-
实参高阶函数
sorted(序列,key=函数)
函数 - 有且只有一个参数(指向/代表序列中的而每个元素);有一个返回值(比较返回值的大小进行排序 - 排序标准)
nums = [13, 32, 45, 12, 54, 67, 77, 78, 562] print(sorted(nums, key=lambda item: item % 10, reverse=Ture)) # 练习:将dates中的元素按照对应的数值大小排序 dates = [23, '78', 56, '34', '102', 79] print(sorted(dates, key=lambda item: int(item)))
map的用法
-
用法一:
map(函数,序列) - 通过原序列中的元素进行指定的变换后产生一个新的序列
a. 函数 - 有且只有一个参数(指向/代表后面的序列中的元素);有一个返回值(新序列中的元素)
-
用法二:
map(函数,序列1,序列2) - 产生一个新的序列,新序列中的元素是序列1和序列2中的元素通过指定的变换产生的
a. 函数 - 有且只有两个参数(这两个参数分别指向序列1,序列2);有一个返回值(新序列中的元素)
nums = [1,2,3,4] nums1 = map(lambda x: x**2, nums) # 产生一个新的列表,列表中的元素是seq1中加上seq2中的元素 seq1 = [1,2,3,4,5,6] seq2 = [2,3,4,5,6,7] nums2 = map(lambda x, y: x + y, seq1, seq2) # 练习: 将tels中所有的电话号码依次添加到students中的每个字典中,产生一个新的列表 students = [ {'name': 'stu1', 'age': 20, 'score': 67, 'sex': '男'}, {'name': 'stu2', 'age': 18, 'score': 82, 'sex': '女'}, {'name': 'stu3', 'age': 19, 'score': 54, 'sex': '女'}, {'name': 'stu4', 'age': 22, 'score': 77, 'sex': '男'}, {'name': 'stu5', 'age': 21, 'score': 56, 'sex': '男'}, {'name': 'stu6', 'age': 18, 'score': 78, 'sex': '男'}, {'name': 'stu7', 'age': 16, 'score': 100, 'sex': '女'} ] tels = ['110', '120', '114', '119', '12306', '10086', '10000'] # 方法一: def new(dic1, dic2): dic1.setdefault('tel', dic2) return dic1 result = list(map(new, students, tels)) print(result) # 补充:eval函数的用法 # eval(序列字符串) - 将满足规范格式的序列的字符串转换成序列 result = list(map(lambda x, y: eval(f'{str(x)[:-1]},"tel":"{y}"}}'), students, tels)) result1 = list(map(lambda x, y: eval(str(x).replace('}', f',"tel":"{y}"}}')), students, tels)) print(result)
reduce的用法
-
使用前需要从functools模块导入
-
用法一(了解):
reduce(函数,序列) - 将序列中的元素通过指定的规划合并成一个数据
a. 函数 - 有且只有两个参数,第一个参数第一次调用的时候指向序列中的第一个元素,从第二次开始都是指向上一次的运算结果;第二个参数指向除第一个元素以外的所有元素;
返回值是每次合并的结果(用来制定合并规则)
-
用法二(掌握):
reduce(函数,序列,初始值)
a. 函数:
第一个参数:第一次指向初始值,从第二次开始参数指向上一次合并的结果
第二个参数:指向序列中所有的元素
返回值:每个合并的结果(制定)
# ==============用法一(了解)===================== nums2 = [29, 38, 90] result = reduce(lambda x, y: str(x) + str(y)) print(result) # ================方法二===================== nums = [13, 32, 45, 12, 54, 67, 77, 78, 562] def func2(x, y): return x + y result = reduce(func2, nums, 0) print(result) # 练习:计算[29, 38, 90, 34, 67]元素个位数的和 nums3 = [29, 38, 90, 34, 67] result = reduce(lambda x, y: x + y % 10, nums3, 0) print(result) # 练习:拼接nums中所有数字的个位数:"98047" result = reduce(lambda x, y: x + str(y % 10), nums3, '') print(result) # 练习:求students中所有学生的总分数 result = reduce(lambda x, y: x + y['score'], students, 0) print(result)
02-装饰器
1.什么是装饰器
装饰器是一种专门用来给其他函数添加功能的函数
2.给函数添加统计时间的功能
-
方式一:直接在函数中添加新功能(缺点,同样的功能会写很多次)
def func1(): start = time.time() print('hello world') end = time.time() print('执行时间:', end - start) func1()
-
方式二:定义一个实参高阶函数来给指定函数添加功能(缺点:主次颠倒)
def count_time(func): start = time.time() func() end = time.time() print('执行时间:', end - start) def fun2(num=131): print(num ** 10) count_time(fun2)
3.无参装饰器的写法
-
无参装饰器的写法
""" 装饰器 = 实参高阶函数+返回值高阶函数+糖语法 套路: def 函数名1(参数1): def 函数名2(*args, **kwarg): result = 参数1(*args, **kwarg) 实现添加功能的代码段 return = result return 函数名2 说明: 函数名1 - 装饰器的名字(按照当前装饰器添加的功能来命名) 参数1 - 这个参数是用来接收被添加功能的函数(指向原函数),一般直接命名为:func 函数名2 - 表示的是在原函数的基础上添加完功能的新函数,一般直接命名成一个固定的名字:test、new_func 使用装饰器:在需要添加功能的函数的定义前加:@装饰器 """ # 示例1:写一个装饰器,在原函数结束后打印'========函数结束=========' def stamp(func): def new_func(*args, **kwargs): result = func(*args, **kwargs) print('=======函数结束==========') return result return new_func @stamp def func3(x, y): return x + y print(func3(1, 2)) # 示例2:写一个装饰器,如果原函数的返回值是整数,就返回这个数的二进制形式 def binary(func): def new_func(*args, **kwargs): result = func(*args, **kwargs) if type(result) != int: return result else: return bin(result) return new_func @binary def func4(x, y): return x + y print(func4(10, 20))