day11_实参高阶函数

1.函数匿名

没有函数名的函数

函数名 = lambda 形参列表:返回值

相当于

def 函数名(形参列表):
    return 返回值

sum1 = lambda num1,num2:num1+num2
sum1 = lambda num1,num2:num1+num2
print(sum1(1,2))
print(sum1(num1=100,num2=200))

匿名的本质还是函数,之前函数中除了定义函数的语法以外的内容都适用于匿名

用处:简洁,不用用def来定义函数

练习:写一个匿名函数判断指定的年是否是闰年

year = int(input())
is_leapyear = lambda year:True if (year%400 == 0 or (year%4==0 and year%100!=0)) else False
print(is_leapyear(year))

2.函数就是变量

python中定义函数就是定义类型是function的变量,函数名就是变量名

普通变量能做的事情,函数都可以做

返回值是高阶函数:如果一个函数的返回值是函数,那么这个函数就是返回值高阶函数

def func4():
    def t2():
        print('你好')

    return t2


result = func4()()

练习

list3 = []
for x in range(5):
    list3.append(lambda i:x*i)
print(list3[0](2))
print(list3[1](2))
print(list3[2][2])

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]

调用函数的时候才会执行,所以x=4的时候才会调用,x=4,4*2=8

3.实参高阶函数的应用

python中常用的实参高阶函数:max、min、sorted、map、reduce

1) max和min

students = [{'name':'小一','age':18,'score':92},
            {'name':'小二','age':14,'score':93},
            {'name':'小三','age':15,'score':94},
            {'name':'小四','age':16,'score':95},
            {'name':'小五','age':17,'score':97}
            ]

max(序列,key=函数) - 按照key对应的函数指定的规则来获取序列中元素的最大值
函数的要求:

​ a.有且只有一个参数(这个参数指向的是序列中的元素);

​ b.有一个返回值(比较大小的对象)

# 个位数最大:
nums = [29, 32, 4, 35, 57]
result = max(nums, key=lambda item: item % 10)
print(result)
# nums中最大的数
result = max(nums,key=lambda item:item)
print(result)
# 获取tels中尾号最大的元素
tels = ['17289993', '2828902', '78289191', '1910290']
max_tel = max(tels,key=lambda item:item[-1])
print(max_tel)

2) sorted(序列,key= 序列)

result = sorted(nums,key=lambda item:item%10)
print(result)
# 按学生分数从大到小排序
students = [
    {'name': '小明', 'age': 18, 'score': 92},
    {'name': '张三', 'age': 24, 'score': 99},
    {'name': '李四', 'age': 30, 'score': 87},
    {'name': '王五', 'age': 16, 'score': 62}
]
result = sorted(students,key=lambda item:item['score'],reverse=True)
print(result)

3) map(函数,序列)

将序列中的元素按照函数指定的规则转换成一个新的序列

函数的要求:

​ a. 有且只有一个参数(指向序列中的每个元素)

​ b.需要一个返回值(返回值就是新序列中的元素)

nums = [18,23,9,67,16]
new_nums = map(lambda item:item%10,nums)
print(list(new_nums))
# map提取所有手机号码后四位
tels = ['15283131024','15283131033','15283131544','15283132012']
new_tels = map(lambda item:item[-4:],tels)
print(list(new_tels))

4) map(函数,序列1,序列2)

函数要求:

​ a. 有且只有两个参数(分别指向两个序列中的元素)

​ b.需要一个返回值(返回值就是新序列中的元素)

names = ['张三', '李四', '王五', '小张', '小马', '小花']
scores = [90, 89, 87, 86, 85, 84]
result = list(map(lambda item1,item2:{'name':item1,'scores':item2},names,scores))
print(result)
#练习
list1 = [10, 2, 78, 90, 16]
str1 = 'abcde'
list2 = [(10, 20), (3, 7), (9, 10), (103, 56), (1, 2)]
# ['10a20', '2b7', '78c10', '90d56', '16e2']
result = list(map(lambda x,y,z:f'{x}{y}{z[-1]}',list1,str1,list2))
print(result)

5) reduce(函数,序列,初始值)

将序列中的元素按照函数指定的规则合并成一个数据

函数的要求:

​ 1)有且只有两个参数

​ 第一个参数:第一次指向初始值,从第二次开始指向上一次的计算结果

​ 第二个参数:指向序列中的每个元素

​ 2)描述合并规则

nums = [20,30,40,67]
result = reduce(lambda x,y:x+y,nums,0)
print(result)
# 0  20 --->  20
# 20 30 --->  50
# 50 40 --->  90
# 90 67 --->  157
# [18,90,89,78,67] 求元素个位数的和
nums = [18,90,89,78,67]
result = reduce(lambda x,y:x+y%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,y:x+y['price']*y['count'],goods,0)
print(result)
# 练习1 :乘积
nums = [18, 90, 89, 78, 67]
result = reduce(lambda x, y: x * y, 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
nums = [18, 'abc', 10.3, True, '你好']
new_nums = [x for x in nums if (type(x)==int or type(x)==float)]
result = reduce(lambda x, y: x + y, new_nums, 0)
print(result)
result_1 = reduce(lambda x, item: x + (item if type(item) in (int, float) else 0), nums, 0)
print(result_1)

作业

  1. 已经列表points中保存的是每个点的坐标(坐标是用元组表示的,第一个值是x坐标,第二个值是y坐标)
 points = [
   (10, 20), (0, 100), (20, 30), (-10, 20), (30, -100)
 ]

以下问题使用实参高阶函数来解决

1)获取列表中y坐标最大的点

 y_max= max(points,key=lambda item:item[1])
    # 改:绝对值的话,加一句:
 result = [x for x in points if x[-1]==y_max[-1]]

2)获取列表中x坐标最小的点

 x_min = min(points,key=lambda item:item[0])
    #改:
 result = [x for x in points if x[0]==x_min[0]]

3)获取列表中距离原点最远的点

 dis_far = max(points,key=lambda item:(item[0]**2+item[1]**2)**0.5)

不用再开方,判断是一样的

dis_far = max(points,key=lambda item:(item[0]**2+item[1]**2))

result = [x for x in points if x[0]**2+x[1]**2==dis_far
print(resu)

4)将点按照点到x轴的距离大小从大到小排序

 new_points = sorted(points,key=lambda item:item[1])

new_points = sorted(points,key=lambda item:abs(item[-1]),reverse=True)
  1. 求列表 nums 中绝对值最大的元素
 nums = [1.2,34,-56,'a']
 abs_max = max(nums,key=lambda item:abs(item) if type(item)in(int,float) else 0)
 print(abs_max)
  1. 已经两个列表A和B,用map函数创建一个字典,A中的元素是key,B中的元素是value
 A = ['name', 'age', 'sex']
 B = ['张三', 18, '女']
 新字典: {'name': '张三', 'age': 18, 'sex': '女'}
A = ['name', 'age', 'sex']
B = ['张三', 18, '女']
dict1 =list(map(lambda item1,item2:{item1:item2},A,B))
print(dict1)

	A = ['name', 'age', 'sex']
	B = ['张三', 18, '女']
	dict1 =dict(map(lambda item1,item2:(item1,item2),A,B))
	print(dict1)
  1. 已经三个列表分别表示4个学生的姓名、学科和班号,使用map将这个三个列表拼成一个表示每个学生班级信息的的字典
 names = ['小明', '小花', '小红', '老王']
 nums = ['1906', '1807', '2001', '2004']
 subjects = ['python', 'h5', 'java', 'python']
 结果:{'小明': 'python1906', '小花': 'h51807', '小红': 'java2001', '老王': 'python2004'}
stu_dict = list(map(lambda item1,item2,item3:{item1:item2+item3},names,subjects,nums))

result = dict(map(lambda x,y,z:(x,z+y),names,nums,subjects))
print(result)
  1. 已经一个列表message, 使用reduce计算列表中所有数字的和(用采用列表推导式和不采用列表推导式两种方法做)
 message = ['你好', 20, '30', 5, 6.89, 'hello']
 结果:31.89
 #不用推导式
 sum_message = reduce(lambda i1, i2: i1 + (i2 if type(i2) in (int, float) else 0), message, 0)
 # 用列表推导式
 new_message = [x for x in message if type(x) in(int,float)]
 sum_message = reduce(lambda i1,i2:i1+i2,new_message,0)

	result = reduce(lambda x,item:x+item,[i for i in message if type(i)in (int,float)],0)
	print(result)
  1. 已知一个字典列表中保存的是每个学生各科的成绩,

    1)计算并添加每个学生的平均分

    2)按照平均分从高到低排序

 studens = [
   {'name': 'stu1', 'math': 97, 'English': 67, 'Chinese': 80},
   {'name': 'stu2', 'math': 56, 'English': 84, 'Chinese': 74},
   {'name': 'stu3', 'math': 92, 'English': 83, 'Chinese': 78},
   {'name': 'stu4', 'math': 62, 'English': 90, 'Chinese': 88}
 ]
 
 # 计算平均分
 studens = [
   {'name': 'stu1', 'math': 97, 'English': 67, 'Chinese': 80, 'avg':81},
   {'name': 'stu2', 'math': 56, 'English': 84, 'Chinese': 74, 'avg':71},
   {'name': 'stu3', 'math': 92, 'English': 83, 'Chinese': 78, 'avg':87},
   {'name': 'stu4', 'math': 62, 'English': 90, 'Chinese': 88, 'avg':80}
 ]
 
 # 按照平均分从高到低排序
 ...
students_avr = list(map(lambda item:(item['math'] + item['English'] + item['Chinese']) // 3, students))
for x in range(len(students)):
    students[x]['avr'] = students_avr[x]
result  = sorted(students,key=lambda item:item['avr'],reverse=True)

def temp(item):
    item['avg'] = int((item['math']+item['English']+item['Chinese'])/3)
    return item
new_students = list(map(temp,students))
print(new_students)
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值