day11 高阶函数
高阶函数
1.函数就是变量
python中定义函数就是定义类型是function的变量,函数名就是变量名
变量能做的事情,函数都能做
a = 10
d = 'abc'
e = [10, 20, 30]
b = lambda x: x*2
# def b(x):
# return x*2
c = {'a': 10, 'b': 100}
print(type(a), type(b), type(c))
x = 100
def func1():
print('我是一个函数')
1)一个变量可以给另外一个变量赋值
y = x
print(y+100)
z = func1
z()
2)修改变量的值
# x = 'abc'
# print(x+'123', x.replace('a', '100'))
# #
# func1 = 100
# # func1() # TypeError: 'int' object is not callable
# print(func1, func1+200)
3)变量作为序列的元素
list1 = [x, 200]
print(list1) # [100, 200]
print(list1[0] - 100)
list2 = [func1, 200, func1()]
print(list2) # [<function func1 at 0x10a776710>, 200, None]
list2[0]() # func1()
4)变量作为函数的参数
def func2(m):
print(f'x:{m}')
a = 100
func2(a)
func2(func1)
5)变量作为函数的返回值
def func3():
# s = 100
def s():
print('我是小函数')
return s
# print(func3()-50)
func3()() # s()
面试题
list3 = []
for i in range(5):
list3.append(lambda x:x*i)
print(list3[1](2))
print(list3[2](2))
"""
i = 0: [lambda x:x*i]
i = 1: [lambda x:x*i, lambda x:x*i]
i = 2: [lambda x:x*i, lambda x:x*i, lambda x:x*i]
i = 3: [lambda x:x*i,lambda x:x*i,lambda x:x*i,lambda x:x*i]
i = 4: [lambda x:x*i, lambda x:x*i, lambda x:x*i, lambda x:x*i, lambda x:x*i]
list3 = [lambda x:x*i, lambda x:x*i, lambda x:x*i, lambda x:x*i, lambda x:x*i]
lambda x:x*i
"""
print(list3[1](2)) # 8
print(list3[2](2)) # 8
实参高阶函数
1.实参高阶函数
参数是函数的函数就是实参高阶函数
# func1就是实参高阶函数
def func1(x):
print(x())
def func2(m=10):
print('你好!')
func1(func2)
2.系统常见实参高阶函数的使用
1)max、min
"""
1)max(序列) - 比较序列中元素的大小来获取值最大的元素
2)max(序列, key=函数) - 函数决定求最大值的时候的比较对象
参数key的要求:a.是一个函数 b.这个函数有且只有一个参数(这个参数指向的就是序列中的元素)
c.函数要有一个返回值(比较对象)
"""
# 求列表中个位数最大的元素
nums = [19, 78, 76, 55, 30, 12]
# def f1(item):
# return item % 10
# result = max(nums, key=f1)
result = max(nums, key=lambda item: item % 10)
print(result)
students = [
{'name': '小明', 'age': 23, 'score': 90},
{'name': '张三', 'age': 30, 'score': 78},
{'name': '小红', 'age': 18, 'score': 82},
{'name': 'Tom', 'age': 26, 'score': 99}
]
# 求所有学生中成绩最高的学生
# def f2(item):
# print(f'item:{item}')
# return item['score']
print(max(students, key=lambda item: item['score']))
# print(max(students, key=f2))
# 求年龄最小的学生
print(min(students, key=lambda item: item['age']))
2)sorted
sorted(序列) - 比较序列中元素的大小对序列中的元素从小到大排序
sorted(序列,key=函数) - 函数决定排序的时候比较大小的比较对象
函数要求:
a.是一个函数
b.需要一个参数(指向序列中的元素)
c.需要一个返回值(比较对象)
nums = [19, 78, 76, 55, 30, 12]
result = sorted(nums)
print(result)
# 练习1:让列表中的元素按照个位数的大小从小到大排序
# nums = [19, 78, 76, 55, 30, 12] -> [30, 12, 55, 76, 78, 19]
nums = [19, 78, 76, 55, 30, 12]
result = sorted(nums, key=lambda item:item%10)
print(result) # [30, 12, 55, 76, 78, 19]
# 练习2:将students按照学生的年龄从大到小排序
students = [
{'name': '小明', 'age': 23, 'score': 90},
{'name': '张三', 'age': 30, 'score': 78},
{'name': '小红', 'age': 18, 'score': 82},
{'name': 'Tom', 'age': 26, 'score': 99}
]
result = sorted(students, key=lambda item: item['age'])
print(result)
3)map
用法一:原序列 -> 新序列
map(函数,序列) -> 将序列按照指定的方式进行转换,返回值是一个map对象(map对象是序列)
函数:a.有一个参数(指向原序列中的元素) b.需要一个返回值(新序列中的元素)
用法二:
map(函数,序列1,序列2) - 根据序列1和序列2创建一个新的序列
函数:a.有两个参数,分别指向两个序列中元素 b.需要一个返回值(新序列中的元素)
# 用法一
nums = [19, 78, 76, 55, 30, 12]
result = map(lambda item: item%10, nums)
print(list(result))
result = map(lambda item: item*2, nums)
print(list(result))
# 用法二
names = ['张三', '李四', '小明', '小花']
ages = [19, 29, 30, 17]
# [{'name': '张三', 'age': 19}, {'name':'李四', 'age': 29},...]
result = map(lambda item1, item2: {'name':item1, 'age': item2}, names, ages)
print(list(result))
# 练习:获取班级所有学生的总成绩
c = [90, 89, 88, 99, 27, 76, 56]
e = [98, 78, 66, 82, 90, 12, 78]
m = [23, 98, 100, 72, 69, 27, 96]
result = map(lambda i1, i2, i3: i1+i2+i3, c, e, m)
print(list(result))
4)reduce
reduce(函数,序列,初始值)
函数的要求:
a.需要两个参数:第一个参数 - 第一次指向初始值;从第二次开始指向上一次的运算结果 第二个参数 - 指向序列中的每个元素
b.需要一个返回值(决定运算规则)
from functools import reduce
# 累积求和
nums = [10, 89, 78, 20]
# result = reduce(lambda s, item: s+item, nums, 0)
def f1(s, item):
print(f's:{s}, item:{item}')
return s+item
result = reduce(f1, nums, 0)
print(result) # 197
# f1(0, 10) -> 10
# f1(10, 89) -> 10+89->99
# f1(99, 78) -> 99+78 -> 177
# f1(177, 20) -> 177+20 -> 197
# 累积求乘积
nums = [8, 9, 5, 2]
result = reduce(lambda s, item: s*item, nums, 1)
print(result)
# 将数字序列中的元素全部拼接在一起
# [10, 89, 78, 20] -> 10897820
nums = [10, 89, 78, 20]
result = reduce(lambda s, item: s+str(item), nums, '')
print(result)
# f('', 10) -> ''+str(10) -> '10'
# f('10', 89) -> '10'+str(89) -> '1089'
# ....
# nums = ['10', '89', '78', '20']
无参装饰器
1.什么是装饰器
作用:装饰器是用来给函数添加功能
本质:就是一个函数(实参高阶函数+返回值高阶函数+糖语法)
用法(套路):
"""
def 函数名1(参数1):
def 函数名2():
新增功能的代码
调用原函数的代码: 参数1()
return 函数名2
说明:
1) 函数名1 - 装饰器的名称,根据新增的功能来命名
2) 参数1 - 需要添加功能的函数(原函数), 一般命名成f、fn
3) 函数名2 - 添加完功能的新函数的函数名, new_f、new_fn
"""
# 练习:写一个装饰器,在函数开始执行的时候打开 'start!'
def start(f):
def new_f(*args, **kwargs):
print('start!')
re = f(*args, **kwargs)
return re
return new_f
@start
def func11():
print('hello world!')
@start
def func22(a, b):
return a*b
func11()
func22(10, 29)