函数进阶
一、函数就是变量
定义函数的时候,其实就是在定义一个类型function的变量,函数名就是变量名;普通变量能做的事情函数都可以做。
def a():
print('函数1')
b = [1, 2, 3]
- 查看数据类型
print(type(b)) # <class 'list'>
print(type(a)) # <class 'function'>
- 使用变量中保存的数据
print(b) # [1, 2, 3]
print(a) # <function a at 0x000002B209854A68>
b2 = b
print(b2[1]) # 2
a2 = a
a2() # 函数1
- 修改变量的值
b = 100
print(b) # 100
a = 'abc'
print(a) # abc
- 变量可以作为列表元素
x = 100
def y():
return 'abc'
list1 = [x, y, y()]
print(list1) # [100, <function y at 0x00000234D6504B88>, 'abc']
print(list1[0] * 2, list1[0] % 10) # 200 0
print(list1[2][0], list1[2].replace('a', 'A')) # a Abc
二、实参高阶函数
1.什么是实参高阶函数
如果一个函数的参数是函数,那么这个函数就是实参高阶函数。
def func5(x):
# x = lambda item: 'a'
# x = test
# print(test(100)) -> print(1000)
# print(test(100)) -> print('a')
print(x(100))
def test(a):
# a = 100
return a*10 # return 1000
func5(test)
func5(lambda item: 'a')
func5就是一个实参高阶函数。
2.实参高阶函数的应用
除了写装饰器以外,一般不会自己去定义实参高阶函数,主要是使用系统已经定义好的实参高阶函数。
系统中常用的实参高阶函数:max、min、sorted、reduce、map。
使用reduce前,需要在最上面添加 from functools import reduce 。
- max、min
max(序列)\min(序列) - 获取指定序列中元素的最大值\最小值
max(序列, key)\min(序列, key) - 参数key的类型是函数
key的要求:a.是一个函数 b.有且只有一个参数,并且这个参数指向的是序列中的每一个元素 c.需要一个返回值,这个返回值就是比较大小的时候比较对象
nums = [1012, 34, 756, 78, 29]
print(max(nums))
print(max(nums, key=lambda item: item)) # 78; 比较元素本身的大小
print(max(nums, key=lambda item: item % 10)) # 29
def test(item):
sum1 = 0
for x in str(item):
sum1 += int(x)
print('sum1:', sum1)
return sum1
print(max(nums, key=test)) # 78
list1 = ['abc', 'klsysss', 'hajA', 'shfjz']
print(max(list1)) # 'shfjz'
print(max(list1, key=lambda item: len(item))) # klsysss
max的实现原理
def yt_max(seq, key=None):
list1 = list(seq)
temp = list1[0]
if not key:
for x in list1:
if x > temp:
temp = x
else:
for x in list1:
if key(x) > key(temp):
temp = x
return temp
print(yt_max([10, 34, 78, 80, 19]))
print(yt_max([10, 34, 78, 80, 19], key=lambda item: item % 10))
练习:求students中分数最高的学生
students = [
{'name': '小明', 'score': 90, 'age': 23},
{'name': '小红', 'score': 95, 'age': 22},
{'name': '小黑', 'score': 60, 'age': 25}
]
print(max(students, key=lambda item: item['score'])['name']) # 小红
求年龄最小的学生
print(min(students, key=lambda item: item['age'])['name']) # 小红
- sorted
sorted(序列) - 将序列按照序列元素的大小进行排序,返回排序后的列表
sorted(序列, key)
key的要求: a.是一个函数 b.函数有且只有一个参数,并且这个参数指向的是序列中的每一个元素 c.需要一个返回值,这个返回值就是比较大小的比较对象
nums = [73, 69, 57, 28, 71, 54]
print(sorted(nums)) # [28, 54, 57, 69, 71, 73]
# 按照个位数的大小从小到大排序:[71, 73, 54, 57, 28, 69]
print(sorted(nums, key=lambda item: item % 10)) # [71, 73, 54, 57, 28, 69]
# 将students按照分数值从大到小进行排序
students = [
{'name': '小明', 'score': 90, 'age': 23},
{'name': '小红', 'score': 95, 'age': 22},
{'name': '小黑', 'score': 60, 'age': 25}
]
print(sorted(students, key=lambda item: item['score'], reverse=True))
# [{'name': '小红', 'score': 95, 'age': 22},
# {'name': '小明', 'score': 90, 'age': 23},
# {'name': '小黑', 'score': 60, 'age': 25}]
- map
用法一:map(函数, 序列) - 将序列按照函数给定的规划创建成一个新的序列
函数的要求:a.是一个函数 b.有一个参数(指向序列中的每个元素) c.一个返回值(产生新元素的规则)
用法二:map(函数, 序列1, 序列2) - 将序列按照函数给定的规则创建成一个新的序列
函数的要求:a.是一个函数 b.有两个参数(第一个参数指向第一个序列中的元素,第二个参数指向第二个序列中的元素) c.一个返回值(产生新元素的规则)
注意:两个序列中元素个数一致
例题1:将序列中每个数的个位数取出来产生一个新的列表
nums = [23, 35, 67, 91, 25, 45]
new_nums = list(map(lambda item: item % 10, nums))
print(new_nums) # [3, 5, 7, 1, 5, 5]
例题2:使用map创建一个新的列表,元素是nums中元素的100倍
nums = [0.23, 0.45, 0.89, 0.12, 0.65]
new_nums = list(map(lambda item: int(item * 100), nums))
print(new_nums) # [23, 45, 89, 12, 65]
new_nums = list(map(lambda item: f'{item:.2%}', nums))
print(new_nums) # ['23.00%', '45.00%', '89.00%', '12.00%', '65.00%']
strs = ['abc', 'how', 'you', 'love']
nums = [1, 20, 4, 60]
new_list = list(map(lambda x, y: x + str(y), strs, nums))
print(new_list) # ['abc1', 'how20', 'you4', 'love60']
prices = [67, 256, 304, 89] # 商品原价
discount = [1, 0.8, 0.75, 0.95] # 折扣
new_list = list(map(lambda x, y: x * y, prices, discount))
print(new_list) # [67, 204.8, 228.0, 84.55]
- reduce
方法一:reduce(函数, 序列) - 将序列中所有的元素按照函数规定的操作进行合并
函数的要求:a.是一个函数 b.有两个参数(第一个参数第一次指向的是序列的第一个元素,从第二次开始指向的是上次运算的结果;第二个参数指向的是序列第二个开始的每个元素)
方法二:reduce(函数, 序列, 默认值) - 将序列中所有的元素按照函数规定的操作进行合并
函数的要求:a.是一个函数 b.有两个参数(第一个参数第一次是初始值,从第二次开始指向的是上次运算的结果;第二个参数指向的是序列的每个元素)
nums = [12, 34, 45, 67, 89, 23]
# 求和
result = reduce(lambda x, y: x + y, nums)
print(result) # 270
# 合并成一个字符串
result = reduce(lambda x, y: str(x) + str(y), nums)
print(result) # 123445678923
# 求乘积
result = reduce(lambda x, y: x * y, nums)
print(result) # 2518055640
students = [
{'name': '小明', 'score': 90, 'age': 23},
{'name': '小红', 'score': 95, 'age': 22},
{'name': '小黑', 'score': 60, 'age': 25}
]
# 求所有分数的和
result = reduce(lambda x, y: x + y['score'], students, 0)
print(result) # 245
三、列表推导式
1.什么是列表推导式 - 用来快速创建列表
方法一:列表 =[表达式 for 变量 in 序列] - 产生一个新的列表,变量在序列中每取一个元素就将表达式的值添加到新列表中。
方法二:列表[表达式 for 变量 in 序列 if 条件语句]
方法三:列表 = [表达式 for 变量1 in 序列 for 变量2 in 序列]
列表 = [表达式 for 变量1 in 序列 for 变量2 in 序列 if 条件语句]
list1 = [x * 2 for x in range(1, 5)]
print(list1) # [2, 4, 6, 8]
list2 = [f'{x:0>3}' for x in range(10, 15)]
print(list2) # ['010', '011', '012', '013', '014']
list3 = [x for x in range(10) if x % 2]
print(list3) # [1, 3, 5, 7, 9]
list4 = ['str' + str(x) for x in [10, 34, 15, 11, 78, 90, 99] if x % 2]
print(list4) # ['str15', 'str11', 'str99']
nums = [23, 89, 67, 56, 10, 33]
list5 = [x % 10 for x in nums]
print(list5) # [3, 9, 7, 6, 0, 3]
list6 = [f'{x}:{y}' for x in range(1, 5) for y in range(10, 14)]
print(list6)
# ['1:10', '1:11', '1:12', '1:13', '2:10', '2:11', '2:12', '2:13', '3:10',
# '3:11', '3:12', '3:13', '4:10', '4:11', '4:12', '4:13']
list7 = [f'{x}:{y}' for x in range(1, 5) for y in range(10, 14) if x % 2 and y % 2 == 0]
print(list7) # ['1:10', '1:12', '3:10', '3:12']
2.字典推导式
字典 = {key:value for 变量 in 序列}
字典 = {key:value for 变量 in 序列 if 条件语句}
dict1 = {x: x * 2 for x in range(5)}
print(dict1) # {0: 0, 1: 2, 2: 4, 3: 6, 4: 8}
dict2 = {'a': 1, 'b': 2, 'c': 3}
dict3 = {value: key for key, value in dict2.items() if type(value) not in (dict, list, set)}
print(dict3) # {1: 'a', 2: 'b', 3: 'c'}