day-13函数应用和模块
1、匿名函数 - 没有名字的函数
lambda 形参列表:返回值
相当于:
def(形参列表):
return 返回值
匿名函数的本质还是函数,除了定义的语法结构和普通函数不一样,其他都一样
案例1:求任意两个数的和
def sum1(num1, num2):
return num1 + num2
sum1 = lambda num1=1, num2=2: num1 + num2
print(sum1(10, 29))
print(sum1(num1=100, num2=200))
print(sum1())
1.写一个函数,判断指定的年是否是闰年
def is_leap_year(year: int):
return (year % 4 == 0 and year % 100 != 0) or (year % 400 == 0)
is_leap_year = lambda year: (year % 4 == 0 and year % 100 != 0) or (year % 400 == 0)
print(is_leap_year(2021))
练习:写一个匿名函数,可以获取任意一个整数的十位数
shi = lambda num: num // 10 % 10
print(shi(1823))
给实参高阶函数传参的时候,函数对应的参数优先考虑使用匿名函数= lambda num: num // 10 % 10
匿名函数的应用 - 实参高阶函数传参的时候,函数对应的函数优先考虑使用匿名函数
函数对应的参数的传参方式:1. 传普通函数的函数名 2.传匿名函数
def func1(x):
x = temp
x = lambda a=1: a*10
x() # temp() x()
如果一个函数的参数是函数(实参高阶函数),这个参数怎么传参: 1. 传普通函数的函数名 2.传匿名函数
def temp():
print(‘临时函数’)
func1(temp)
func1(lambda a=1: a*10)
def func2(x):
x = lambda a: 10
print(x(10) + 100)
x的要求:a.是个函数 b.这个函数可以接受一个实参 c.这个函数的返回值必须是数字
func2(lambda a: 10)
2、实参高阶函数 - 如果一个函数有一个参数是函数,那么这个函数就是实参高阶函数
函数对应的参数的传参方式:1、传普通参数的函数名 2、传匿名函数
常用实参高阶函数
01、max、min、sorted(sort)
max(序列) - 求序列中最大的元素(直接比较每个元素本身的大小求最大值)
max(序列,key=函数) - 按照函数指定的规则比较序列中的元素求出最大值
函数的要求:a.有且只有一个参数,这个参数会指向序列中的每个元素
b.需要一个返回值;返回值就是比较对象(将参数看成序列中的元素,在返回值这个位置来描述比较的值和元素之间的关系)
求nums中值最大的元素
nums = [19, 67, 28, 100, 23]
print(max(nums))
print(max(nums, key=lambda item: item))
案例:求nums中个位数最大的元素: 19
nums = [19, 67, 28, 100, 23]
print(max(nums, key=lambda item: item % 10))
案例2:求nums中各个位数之和最大的元素: 67
nums = [19, 67, 28, 100, 23]
方法1:
def temp(item):
s = 0
for x in str(item):
s += int(x)
return s
result = max(nums, key=temp)
print(result)
方法2:
result = max(nums, key=lambda item: sum(int(x) for x in str(item)))
print(result)
案例3:求students中分数最高的学生: {‘name’: ‘stu1’, ‘age’: 18, ‘score’: 98, ‘sex’: ‘男’},
students = [
{‘name’: ‘stu1’, ‘age’: 18, ‘score’: 90, ‘sex’: ‘男’},
{‘name’: ‘stu2’, ‘age’: 28, ‘score’: 72, ‘sex’: ‘女’},
{‘name’: ‘stu3’, ‘age’: 24, ‘score’: 57, ‘sex’: ‘女’},
{‘name’: ‘stu4’, ‘age’: 17, ‘score’: 97, ‘sex’: ‘男’},
{‘name’: ‘stu5’, ‘age’: 20, ‘score’: 64, ‘sex’: ‘女’},
]
print(max(students, key=lambda stu: stu[‘score’]))
练习1:求nums中绝对值最小的元素
nums = [-23, 100, 89, -56, -234, 123]
print(min(nums, key=lambda item: item**2))
练习2:将students中所有的元素按照年龄的大小从小到大排序
students.sort(key=lambda stu:stu[‘age’])
print(students)
new_students = sorted(students, key=lambda stu: stu[‘age’])
print(new_students)
02、map - 基于原序列中的元素,通过指定的规则创建一个新的序列
map(函数,序列)
函数的要求:a.有且只有一个参数,参数就指向后面这个序列中的元素
b.有一个返回值,返回值就是新序列中的元素
map(函数, 序列1, 序列2)
函数的要求:a.有且只有两个参数;分别指向后面两个序列中的元素
b.有一个返回值;返回值就是新序列中的元素
map(函数, 序列1, 序列2, 序列3)
函数的要求:a.有且只有三个参数; 分别指向后面三个序列中的元素
b.有一个返回值;返回值就是新序列中的元素
map(函数, 序列1, 序列2, 序列3, … 序列N)
案例1:提取nums中所有元素的个位数: [9, 7, 8, 0, 3]
nums = [19, 67, 28, 100, 23]
result = list(map(lambda item: item % 10, nums))
print(result)
案例2:计算nums中所有元素各个位数的和,得到一个新列表: [10, 13, 10, 1, 5]
nums = [19, 67, 28, 100, 23]
result = list(map(lambda item: sum([int(x) for x in str(item)]), nums))
print(result)
案例3:获取students中所有学生的名字,得到一个新的列表: [‘stu1’, ‘stu2’, ‘stu3’, ‘stu4’, ‘stu5’]
students = [
{‘name’: ‘stu1’, ‘age’: 18, ‘score’: 90, ‘sex’: ‘男’},
{‘name’: ‘stu2’, ‘age’: 28, ‘score’: 72, ‘sex’: ‘女’},
{‘name’: ‘stu3’, ‘age’: 24, ‘score’: 57, ‘sex’: ‘女’},
{‘name’: ‘stu4’, ‘age’: 17, ‘score’: 97, ‘sex’: ‘男’},
{‘name’: ‘stu5’, ‘age’: 20, ‘score’: 64, ‘sex’: ‘女’},
]
result = list(map(lambda item: item[‘name’], students))
print(result)
案例4:
nums = [100, 200, 100, 300, 400]
rates = [0.1, 0.3, 0.25, 0.2, 0.3]
[10, 60, 25, 60, 120]
result = list(map(lambda i1, i2: i1 * i2, nums, rates))
print(result)
案例5:已经两个列表A和B,创建一个字典,A中的元素是key,B中的元素是value
A = [‘name’, ‘age’, ‘sex’]
B = [‘张三’, 18, ‘女’]
新字典: {‘name’: ‘张三’, ‘age’: 18, ‘sex’: ‘女’}
[(‘name’, ‘张三’), (‘age’, 18), (‘sex’, ‘女’)]
result = dict(map(lambda i1, i2: (i1, i2), A, B))
print(result) # {‘name’: ‘张三’, ‘age’: 18, ‘sex’: ‘女’}
03、reduce - 将序列中的元素通过指定的规则合并成一个数据
reduce(函数,序列,初始值)
初始值 - 根据合并方式,初始值一般是0(数值求和)、1(数值求乘积)或者空串(字符串拼接)
函数:a.有且只有两个参数;第一个参数指向初始值,第二个参数指向序列中的每个元素
b.有一个返回值,用来描述合并方式
from functools import reduce
案例1: 求nums中所有元素的和: 0 + 19 + 67 + 28 + 100 + 23
nums = [19, 67, 28, 100, 23]
result = reduce(lambda x, item: x + item, nums, 0)
print(result)
案例2:求nums中所有个位数的和: 0 + 9 + 7 + 8 + 0 + 3
nums = [19, 67, 28, 100, 23]
result = reduce(lambda x, item: x + item % 10, nums, 0)
print(result)
案例3:求nums中所有元素的乘积: 1 * 19 * 67 * 28 *…
nums = [19, 67, 28, 100, 23]
result = reduce(lambda x, item: x * item, nums, 1)
print(result)
案例4:将nums中所有的数合并成一个字符串, ‘19672810023’
‘’ + ‘19’ + ‘67’ + ‘28’ + ‘100’ + ‘23’
nums = [19, 67, 28, 100, 23]
result = reduce(lambda x, item: x + str(item), nums, ‘’)
print(result) ‘19672810023’
案例5:将nums中所有的数十位数合并成一个字符串, ‘16202’
‘’ + ‘1’ + ‘6’ + ‘2’ + ‘0’ + ‘2’ + ‘0’
nums = [19, 67, 28, 100, 23, 9]
result = reduce(lambda x, item: x + str(item // 10 % 10), nums, ‘’)
print(result) 162020
‘’ + ‘1’ + ‘6’ + ‘2’ + ‘0’ + ‘2’ + ‘’
def temp(x, item):
if item >= 10:
return x + str(item)[-2]
return x + ‘’
nums = [19, 67, 28, 100, 23, 9]
result = reduce(temp, nums, ‘’)
print(result) 16202
3、迭代器(iter) - 迭代器是容器(打印看不到的元素且无法统计元素个数且获取元素的时候只能从上往下一个一个的取,并且取一个就少一个)
创建迭代器
01通过类型转换 - 将其他容器转换成迭代器
02创建一个生成器
i1 = iter(‘abc’)
i2 = iter([10, 20, 30, 40, 50])
打印看不到的元素
print(i1) <str_iterator object at 0x7f821e9a7790>
print(i2)
无法统计元素个数
print(len(i1)) 报错!
获取元素
01获取单个元素:next(迭代器)
print(next(i1)) a
print(next(i1)) b
print(next(i1)) c
print(next(i1)) 报错!
print(list(i1)) [ ]
无论以任何方式得到了迭代器中的元素,那么被得到的元素一定会从迭代器中消失
i3 = iter(‘hello’)
result = list(i3)
print(result) [‘h’, ‘e’, ‘l’, ‘l’, ‘o’]
print(next(i3)) 报错!
02遍历
i2 = iter([10, 20, 30, 40, 50])
next(i2)
next(i2)
for x in i2:
print(‘x:’, x)
print(next(i2)) 报错
4、生成器 - 生成器是容器(生成器作为容器保存不是多个数据,而是产生多个数据的算法
创建生成器
调用带有yield关键字的函数,就可以得到一个生成器
def func1():
print(‘=====’)
yield
return 100
result = func1()
print(‘result:’, result)
3.怎么控制生成器中元素的个数和值
生成器能创建多少个数据以及能创建哪些数据,就看执行生成器对应的函数的函数体的时候,
会遇到几次yield,每次遇到yield的时候对应的值是多少
def func2():
yield 100
yield 200
yield 300
for x in range(3):
yield x*1000
gen2 = func2()
print(list(gen2))
4.怎么获取生成器中的元素
和迭代器获取元素的方式一样
print(next(gen2))
print(next(gen2))