Python基础第11讲 - 高阶函数
一、高阶函数
1.满足2个条件任意一个都是高阶函数
2.接收函数作为参数,将函数作为返回值的函数也是高阶函数
当我们使用一个函数作为参数时,实际上我们就是将指定的代码传递给了目标函数
l = [1,2,3,4,5,6,7,8,9,10]
# 定义一个函数,用来检测任意数的偶数
def fn2(i):
if i % 2 == 0:
return True
# 定义一个函数,用来检测任意数的是否大于5
def fn3(i):
if i > 5:
return True
return False
# 定义一个函数 用来检测3的倍数
def fn4(i):
if i % 3 == 0:
return True
return False
# 定义一个函数 可以向制定的列表的所有的偶数保存一个新队的列表并返回
def fn(func,lst):
# # 定义一个函数,用来检测任意数的偶数
# def fn2(i):
# if i % 2 == 0:
# return True
#
# # 定义一个函数,用来检测任意数的是否大于5
# def fn3(i):
# if i > 5:
# return True
# return False
# 创建新的列表
new_list = []
for n in lst:
# 判断奇偶
if func(n):
new_list.append(n)
return new_list
print(fn(fn2,l)) # 检测是否偶数
结果:[2, 4, 6, 8, 10]
print(fn(fn3,l)) # 检测是否大于5
结果:[6, 7, 8, 9, 10]
print(fn(fn4,l)) # 检测是否3的倍数
结果:[3, 6, 9]
二、匿名函数
匿名函数 lambda表达式
lambda表达式用来创建一些简单的函数 他是函数创建另外一种方式
语法: lambda 参数列表 :返回值
filter() 可以从序列中过滤出符合条件的元素,保存一个新的序列当中
参数:1、函数,根据该函数来过滤序列(可迭代结构)
2、需要过滤的序列(可迭代结构)
返回值 过滤后新的序列
匿名函数最大的好处是只会调用一次,用完之后会从内存中消失
匿名函数一般都是作为参数使用,其他地方不用
def fn4(i):
if i % 3 == 0:
return True
return False
print(list(filter(fn4,l)))
结果: [3, 6, 9]
定义一个函数 实现两个数的和
def fn5(a,b):
return a + b
print(fn5(11,11)) # 22
print((lambda a,b:a + b)(11,11)) # 22
将匿名函数赋值给一个变量
fn6 = (lambda dj,sl : dj * sl)
print('总价是:',fn6(50,60))
结果: 总价是: 300
l = [1,2,3,4,5,6,7,8,9,10]
r = filter(lambda i : i % 3 ==0,l)
print(list(r))
结果: [3, 6, 9]
map()
map()函数可以对可迭代对象中所有元素做指定的操作,然后将其添加到一个新的对象中返回
l = [1,2,3,4,5,6,7,8,9,10]
lambda i : i + 1,l
# lambda i : i + 1,l
print(map(lambda i : i + 1,l)) # <map object at 0x038C43F0>
print(list(map(lambda i : i + 1,l))) # [2, 3, 4, 5, 6, 7, 8, 9, 10, 11]
sort() 函数可以列表当中的元素进行排序
关键字 Key 需要函数作为参数,每次都会作为参数
l = [1,2,3,4,5,6,7,8,9,10]
lst = ['bb','aaa','c','dddddddd','eeee']
lst.sort(key=len)
print(lst)
结果:['c', 'bb', 'aaa', 'eeee', 'dddddddd']
lst = [3,2,‘1’,‘6’,4]
lst.sort(key=int)
print(lst) # [‘1’, 2, 3, 4, ‘6’]
print(’-’*60)
sorted()
sorted()会返回一个新的列表
'''
1️⃣ sort
'''
lst = [3,2,'1','6',4]
print('排序前:',lst)
lst.sort(key=int)
print('排序后:',lst)
结果: 排序前: [3, 2, '1', '6', 4]
排序后: ['1', 2, 3, 4, '6']
'''
2️⃣ sorted()
'''
lst = [3,2,'1','6',4]
print('排序前:',lst)
print(sorted(lst,key=int))
print('排序后:',lst)
结果: 排序前: [3, 2, '1', '6', 4]
排序后: [3, 2, '1', '6', 4]
三、闭包
3.1 将函数作为返回值返回,也是一种高阶函数
3.2 通过闭包可以换创建一些只有当前函数才能访问的对象,还可以将一些私有的数据藏到闭包中
3.3 当你有数据不想被人修改和访问的时候,用闭包,保证数据安全性
3.4 形成闭包的条件
3.4.1、函数嵌套
3.4.2、将内部的函数作为返回值返回
3.4.3、内部函数必须使用到外部函数的变量
def fn():
# 函数内部在定义一个函数
def fn2():
a = 10
print('我是fn2',a)
# 在内部函数将fn2作为返回值返回
return fn2
print(fn()) # <function fn.<locals>.fn2 at 0x03299030>
r = fn()
r() # 我是fn2 10
'''
求多个个数的平均值
'''
nums = [50,30,20,10,77]
print(sum(nums)/len(nums)) # 37.4
'''
案例1:
'''
# 创建一个函数来求平均值
nums = []
def avg(n):
# 将元素添加到列表当中
nums.append(n)
# 求平均值
return sum(nums)/len(nums)
print(avg(10)) # 10.0
print(avg(10)) # 10.0
print(avg(60)) # 26.666666666666668
print(avg(20)) # 25.0
用闭包:
'''
案例2:
'''
# 创建一个函数来求平均值
nums = []
def new_avg():
# 创建一个列表 用来保存数据
nums = []
def avg(n):
# 将元素添加到列表当中
nums.append(n)
# 求平均值
return sum(nums)/len(nums)
return avg
a = new_avg()
print(a(10)) # 10.0
print(a(10)) # 10.0
print(a(60)) # 26.666666666666668
print(a(20)) # 25.0
四、装饰器的引用
def add(a,b):
print('计算开始...')
r = a + b
print('计算结束...')
return r
def mul(a,b):
return a * b
r = add(1,2)
# ......
print(r) # 3
4.1 我们可以通过修改函数中的代码来完成,但是会产生一些问题:
1.修改函数中很多
2.不方便后期的维护
3.会违反开闭原则(ocp) 程序设计 要求对程序的扩展,但是要关闭对程序的修改
'''
不修改原函数,来对函数进行扩展
'''
def fn():
print('我是fn函数..')
# 来创建一个新的函数 来对原函数进行扩展
def fn2():
print('开始...')
fn()
print('结束...')
fn2()
结果: 开始...
我是fn函数..
结束...
对add()函数进行扩展
def add(a,b):
r = a + b
return r
def new_add(a,b):
print('开始...')
r = add(a,b)
print('结束...')
return r
r = new_add(1,2)
print(r)
结果: 开始...
结束...
3
五、装饰器的使用
def fn():
print('我是fn函数..')
def add(a,b):
r = a + b
return r
def start_end(old):
# 参数 old 要扩展的函数对象
# 用来对其他函数进行扩展,开始,结束
# 创建一个新的函数
def new_function(*args,**kwargs):
print('开始')
result = old(*args,**kwargs)
print('结束')
return result
# 返回新函数
return new_function
f = start_end(add)
r = f(5,6)
print(r)
结果: 开始
结束
11
5.1 start_end(old) 类似于这样的函数其实就是一个装饰器
5.2 通过装饰器可以在不修改原函数的情况下对函数进行扩展
5.3 在开发当中,都是通过装饰器来扩展函数的功能
@start_end
def say_byby():
print('再见...')
say_byby()
结果: 开始
再见...
结束