高阶函数和装饰器 及作业
-
函数就是变量 - - - 变量能做的函数都可以做(python中定义函数其实就是在定义一个类型是function的变量, 函数名就是变量名;)
-
实参高阶函数(max、min、sorted、map、reduce)
-
max(序列, key=函数)
,min(序列, key=函数)
和列表.sort(key=函数)
与sorted(序列, key=函数)
# 2. max 和 min、sorted """ max(序列, key=函数) min(序列, key=函数) sorted(序列, key=函数) 列表.sort(key=函数) 函数的要求: a. 有且只有一个参数,这个参数指向的数前面序列中的每个元素 b. 需要一个返回值,返回值决定求最大值的时候比较的对象 """ # 求列表nums中个位数最大的元素: 19 nums = [28, 87, 65, 19, 25] result = max(nums, key=lambda item: item % 10) #max(序列, key=函数) print(result) # 19 # 练习:用min获取students中年龄最小的学生 students = [ {'name': '小明', 'age': 18, 'score': 98, 'tel': '187283822'}, {'name': '小红', 'age': 30, 'score': 99, 'tel': '187283827'}, {'name': 'Tom', 'age': 25, 'score': 87, 'tel': '187283821'}, {'name': 'Bob', 'age': 19, 'score': 65, 'tel': '187283820'} ] result = min(students, key=lambda stu: stu['age']) #min(序列, key=函数) print(result) result = max(students, key=lambda stu: stu['score']) #max(序列, key=函数) print(result) # 将列表中的元素按照个位数的大小从小到大排序 nums = [28, 87, 65, 19, 25] result = sorted(nums, key=lambda item: item % 10) #sorted(序列, key=函数) print(result) # [65, 25, 87, 28, 19] students.sort(key=lambda stu: stu['tel'][-1]) #列表.sort(key=函数) print(students)
-
map(函数, 序列)
---- - 将原序列中元素按照指定的标准进行变换,产生一个新的序列""" 函数的要求: a.有且只有一个参数,这个参数指向的是后面这个序列每个元素 b.需要一个返回值,描述新序列中的元素和原序列中元素的关系 2)map(函数, 序列1, 序列2) 函数的要求: a. 有且只有两个参数,这两个参数分别指向后面的两个序列中的元素 b. 需要一个返回值,描述新序列中的元素和原序列中元素的关系 map(函数, 序列1, 序列2, 序列3) """ # 1) [28, 89, 34, 78, 21] -> [8, 9, 4, 8, 1] nums = [28, 89, 34, 78, 21] result = map(lambda item: item % 10, nums) print(list(result)) # [8, 9, 4, 8, 1]
-
reduce(函数, 序列, 初始值)
— - 将序列中所有的元素通过指定的方式合并成一个数据from functools import reduce # 引入reduce函数 """ reduce(函数, 序列, 初始值) 函数的要求: a. 有且只有两个参数:第一个第一次指向初始值,从第二次开始指向上一次的计算结果;第二个参数指向序列中的每个元素 b. 需要一个返回值,返回值用来描述合并规则 """ nums = [20, 34, 45, 10] result = reduce(lambda x, item: x+item, nums, 0) print(result) """ reduce内部执行过程: 循环4次: 第1次 x = 0, item = 20, x = x + item = 0 + 20 = 20 第2次 x = 20, item = 34, x = x + item = 20 + 34 = 54 第3次 x = 54, item = 45, x = x + item = 54 + 45 = 99 第4次 x = 99, item = 10, x = x + item = 99 + 10 = 109 return x """ nums = [2, 4, 5, 6, 3] # 2*4*5*6*3 result = reduce(lambda x, item: x * item, nums, 1) print(result) nums = [2, 4, 5, 6, 3] # '24563' result = reduce(lambda x, item: x + str(item), nums, '') print(result) nums = [2, 4, 5, 6, 3] # '2040506030' result = reduce(lambda x, item: f'{x}{item}0', nums, '') print(result) nums = [23, '45', 10, 2, '30'] # 23+45+10+2+30 result = reduce(lambda x, item: x + int(item), nums, 0) print(result) nums = [23, '45', 10, 2, '30'] # 23+10+2 result = reduce(lambda x, item: x + (item if type(item) == int else 0), nums, 0) print(result) # 求列表中所有学生分数的平均分 students = [ {'name': '小明', 'age': 18, 'score': 98, 'tel': '187283822'}, {'name': '小红', 'age': 30, 'score': 99, 'tel': '187283827'}, {'name': 'Tom', 'age': 25, 'score': 87, 'tel': '187283821'}, {'name': 'Bob', 'age': 19, 'score': 65, 'tel': '187283820'} ] result = reduce(lambda x, item: x + item['score'], students, 0) / len(students) print(result)
-
-
装饰器
-
什么是装饰器
# 1.什么是装饰器 # 装饰器 = 实参高阶函数 + 返回值高阶函数 + 糖语法 # 装饰器是用来给函数添加功能的
-
给函数添加功能
-
装饰器:
from time import time from functools import reduce # 方法三:装饰器 """ 固定写法 def 装饰器名称(需要添加功能的函数): def 添加过功能的新函数(*args, **kwargs): 反函数返回值 = 需要添加功能的函数(*args, **kwargs) 添加新的功能 return 原函数返回值(如果装饰器本身的功能和原函数返回值有关,这个地方就不一定) return 添加过功能的新函数 """ def count_time(f): def new_f(*args, **kwargs): start = time() result = f(*args, **kwargs) end = time() print(f'执行时间:{end - start}') return result return new_f @count_time # 糖语法 @count_time 相当于 func1 = count_time(func1) def func1(): print('hello world!') func1() @count_time # 糖语法 @count_time 相当于 func22 = count_time(func22) def func22(N: int): result = reduce(lambda x, item: x * item, range(1, N + 1), 1) return result # func22 = count_time(func22) print(func22(5))
练习(简单实例):
# 练习1:写一个装饰器,给函数添加功能,然后原函数结束的时候打印一个'end' def add_end(f): def new_f(*args, **kwargs): result = f(*args, **kwargs) print('end') return result return new_f @add_end def func2(): print('hello world!') func2() ''' hello world! end ''' # 练习2:写一个装饰器,将函数的返回值加100。 1 -> 101 def value_add(f): def new_f(*args, **kwargs): result = f(*args, **kwargs) if type(result) in (int, float, bool, complex): return result + 100 return result return new_f @value_add def func33(N: int): result = reduce(lambda x, item: x * item, range(1, N + 1), 1) return result print(func33(4)) ''' 124 '''
-
-
作业
-
为函数写一个装饰器,在函数执行之后输出 after
def add_after(f): def new_f(*args, **kwargs): result = f(*args, **kwargs) print('after') return result return new_f @add_after def print_num(x): print(x) print_num(978) ''' 978 after '''
-
为函数写一个装饰器,把函数的返回值 乘2再返回值
from functools import reduce def num_ride_two(fn): def new_fn(*args, **kwargs): result = fn(*args, **kwargs) if type(result) in (int, float, bool, list, tuple, str): return result*2 return result return new_fn @num_ride_two def new_sum(*args): return reduce(lambda x, y: x + y, args, 0) i = new_sum(12, 10) print(i) # 44
-
写一个装饰器@tag要求满足如下功能:
def tag(fn):
def new_fn(*args, **kwargs):
result = fn(*args, **kwargs)
if type(result) in (int, str, bool, float):
return f'<p>{result}</p>'
return result
return new_fn
@tag
def render(text):
# 执行其他操作
return text
@tag
def render2():
return 'abc'
print(render('Hello')) # 打印出: <p>Hello</p>
print(render2()) # 打印出: <p>abc</p>
-
求列表 nums 中绝对值最大的元素
例如:nums = [-23, 100, 89, -56, -234, 123], 最大值是:-234
nums = [-23, 100, 89, -56, -234, 123] max_abs_num = max(nums, key=lambda item: item ** 2) print(f'最大值是:{max_abs_num}') # 最大值是:-234
-
已经两个列表A和B,用map函数创建一个字典,A中的元素是key,B中的元素是value
A = ['name', 'age', 'sex'] B = ['张三', 18, '女'] 新字典: {'name': '张三', 'age': 18, 'sex': '女'}
A = ['name', 'age', 'sex'] B = ['张三', 18, '女'] new_dict = map(lambda item1, item2: (item1, item2), A, B) print(dict(new_dict)) # {'name': '张三', 'age': 18, 'sex': '女'}
-
已经三个列表分别表示5个学生的姓名、学科和班号,使用map将这个三个列表拼成一个表示每个学生班级信息的的字典
names = ['小明', '小花', '小红', '老王'] nums = ['1906', '1807', '2001', '2004'] subjects = ['python', 'h5', 'java', 'python'] 结果:{'小明': 'python1906', '小花': 'h51807', '小红': 'java2001', '老王': 'python2004'}
names = ['小明', '小花', '小红', '老王'] nums = ['1906', '1807', '2001', '2004'] subjects = ['python', 'h5', 'java', 'python'] class_massage = map(lambda item1, item2, item3: (item1, item2+item3), names, subjects, nums ) print(dict(class_massage)) # {'小明': 'python1906', '小花': 'h51807', '小红': 'java2001', '老王': 'python2004'}
-
已经一个列表message, 使用reduce计算列表中所有数字的和(用采用列表推导式和不采用列表推导式两种方法做)
message = ['你好', 20, '30', 5, 6.89, 'hello'] 结果:31.89
# 不采用列表推导式: from functools import reduce num_sum = reduce(lambda x, item: x+item if type(item) in (int, float) else x, message, 0) print(num_sum) # 31.89 # 采用列表推导式: result = sum([i for i in message if type(i) in (int, float)]) print(result)