day11 函数高阶
一、匿名函数
1.匿名函数 - 没有函数名的函数
函数名 = lambda 形参列表:返回值
相当于:
def 函数名(形参列表):
return 返回值
注意:匿名的本质还是函数,之前函数中除了定义函数的语法以外的内容都适用于匿名函数
# 求两个数的和的匿名函数
sum1 = lambda num1, num2: num1 + num2
print(sum1(10, 20))
# 练习:写一个匿名函数判断指定的年是否是闰年
is_leap_year = lambda year: '闰年' if (year % 4 == 0 and year % 100 != 0) or year % 400 == 0 else '平年'
print(is_leap_year(1990))
二、函数就是变量
1.函数就是变量
python中定义函数就是定义类型是function的变量,函数名就是变量名
普通变量能做的事情函数都可以做
x = lambda num: num*2
print(type(x))
print(x(4)**2)
def func1():
return 100
a = 10
print(type(a), type(func1))
print(func1())
list1 =[func1, func1()]
print(list1, list1[0]())
a = 100
def func2(x):
print(x)
func2(a)
func2(func1)
# func3是一个实参高阶函数 - 如果一个函数的参数是函数,那么这个函数就是实参高阶函数
def func3(x, y, z, m):
# x是长度大于等于2的有序序列
print(x[1])
# y是任何类型的数据
print(y)
# z是字典
print(z['a'])
# m是一个函数
# print(m())
def t1():
print('x')
func3('abc', 100, {'a': 100}, t1())
func3('abc', 100, {'a': 100}, lambda x = 10: x**2)
# func4是返回值高阶函数 - 如果一个函数的返回值就是函数,那么这个函数就是返回值高阶函数
def func4():
# name = '张三'
# return name
def t2():
print('你好!')
return t2
print(func4()())
# 练习:
list3 = []
for x in range(5):
list3.append(lambda i: x*i)
"""
x = 0: [lambda i: x*i]
x = 1: [lambda i: x*i, lambda i: x*i]
x = 2: [lambda i: x*i, lambda i: x*i, lambda i: x*i]
x = 3: [lambda i: x*i, lambda i: x*i, lambda i: x*i, lambda i: x*i]
x = 4: [lambda i: x*i, lambda i: x*i, lambda i: x*i, lambda i: x*i, lambda i: x*i]
"""
# 函数体在未执行之前不会赋值
print(list3[0](2)) # 8
print(list3[1](2)) # 8
print(list3[2](2)) # 8
三、实参高阶函数
1.python中常用的实参高阶函数:max、min、sorted、map、reduce
1)max和min
max(序列,key=函数) - 按照key对应的函数指定的规则获取序列中元素的最大值
函数的要求:1)有且只有一个参数(这个参数指向的是序列中的元素)
2)有一个返回值 (比较大小的对象)
nums = [29, 80, 7, 56, 23]
# 示例1:获取nums中个位数最大的元素
# def temp(item):
# return item % 10
# result = max(nums, key=temp)
# print(result)
result = max(nums, key=lambda num: num % 10)
print(result)
# 示例3:获取tels中尾号最大的元素
tels = ['17289993', '2828902', '78289191', '1910290']
result = max(tels, key=lambda item: item[-1])
print(result)
result = min(tels, key=lambda item: item[-1])
print(result)
result = sorted(tels, key=lambda item: item[-1], reverse=True)
print(result)
2.max、min的原理
print('==============================')
nums = [29, 80, 7, 56, 23]
def temp(item):
print(f'item:{item}')
return item % 10
# result = max(nums, key=temp)
# print(result)
def max_wx(seq:list, *, key=None):
if not key:
m = seq[0]
for x in seq[1:]:
if x > m:
m = x
return m
# 有key的时候
m = seq[0]
for x in seq[1:]:
if key(x) > key(m):
m = x
return m
print((max_wx(nums)))
print(max_wx(nums, key=lambda item:item % 10))
# 示例3
nums = [123, 345, 208, 271]
result = max(nums, key=lambda item: item % 10)
print(result)
result = max(nums, key=lambda item: item // 10 % 10)
print(result)
result = sorted(nums, key=lambda item: item % 10)
print(result)
# 将students按学生的分数从大到小排序
students = [
{'name': '小明', 'age': 18, 'score': 92},
{'name': '张三', 'age': 24, 'score': 99},
{'name': '李四', 'age': 30, 'score': 87},
{'name': '王五', 'age': 26, 'score': 62}
]
result = sorted(students, key=lambda item: item['score'], reverse=True)
print(result)
# 按年龄从小到大排序
students.sort(key=lambda item:item['age'])
print(students)
四、实参高阶函数2
1、map
1)map(函数,序列) - 将序列中的元素按照函数指定的规则转换成一个新的序列
函数的要求:a.有且只有一个参数(指向序列中的每个元素)
b.需要一个返回值(返回值就是新序列中的元素)
2)map(函数,序列1, 序列2)
函数的要求:a.有且只有两个参数(分别指向后面的两个序列的元素)
b.需要一个返回值(返回值就是新序列中的元素)
nums = [18, 72, 90, 67, 16]
new_nums = map(lambda item: item % 10, nums)
print(list(new_nums))
# 练习:使用map提取所有手机号码的后4位
tel = ['15112750651', '13640950711', '18080397806', '18080396806']
result = map(lambda item: item[-4:], tel)
print(list(result))
# 合并成带字典的列表
names = ['小明', '张三', '李四', '王五']
scores = [90, 89, 67, 92]
result = map(lambda item1, item2: {'name': item1, 'score': item2}, names, scores)
print(list(result))
# 练习:
list1 = [10, 2, 78, 90, 16]
str1 = 'abcde'
list2 = [(10, 20), (3, 7), (9, 10), (103, 56), (1, 2)]
result = map(lambda item1, item2, item3: f'{item1}{item2}{item3[-1]}', list1, str1, list2)
print(list(result))
2.reduce
reduce(函数,序列,初始值) - 将序列中的元素按照函数指定的规则合并成一个数据
函数的要求:1)有且只有两个参数
第一个参数:第一个参数第一次指向初始值,从第二次开始指向上一次的计算结果
第二个参数:指向序列中的每个元素
2)描述合并规则
nums =[20, 30, 40, 67]
result = reduce(lambda x, y: x + y, nums, 0)
print(result)
"""
计算过程:
第一次:x = 0, y = 20 ->x+y = 20
第二次:x = 20, y = 30 ->x+y = 50
第三次:x = 50, y = 40 ->x+y = 90
第四次:x = 90, y = 67 ->x+y = 157
"""
# 求个位数的和
nums =[208, 309, 403, 67]
result = reduce(lambda x, item: x + item % 10, nums, 0)
print(result)
# 求所有商品的总价
goods = [
{'name': 'XXX泡面', 'price': 3, 'count': 5},
{'name': 'XX口红', 'price': 312, 'count': 2},
{'name': 'xx矿泉水', 'price': 1, 'count': 10}
]
result = reduce(lambda x, item: x + item['price'] * item['count'], goods, 0)
print(result)
# 练习1:求数字序列中所有元素的乘积
nums = [18, 90, 89, 78, 67]
result = reduce(lambda x, item: x * item, nums, 1)
print(result)
# 练习2:求数字序列中所有个位数的乘积
nums = [18, 90, 89, 78, 67]
result = reduce(lambda x, item: x * (item % 10), nums, 1)
print(result)
# 练习3:提取字符串列表中所有的元素的最后一个字符
# ['abc', 'hello', '你好', '123'] -> 'co好3'
list1 = ['abc', 'hello', '你好', '123']
result = reduce(lambda x, item: x + item[-1], list1, '')
print(result)
# 练习4:计算列表中所有数字元素的和
# [18, 'abc', 10.3, True, '你好'] -> 28.3
list1 = [18, 'abc', 10.3, True, '你好']
def temp(y, x):
for x in list1:
if type(x) in [int, float]:
return y + x
return 0
result = reduce(temp, list1, 0)
# result = reduce(lambda x, item: x + (item if type(item) in [int, float] else 0), list1, 0)
print(result)