高阶函数
满足两个条件任意一个都是高阶函数
1.接受函数作为参数的函数
2.将函数作为返回值的函数
当我们使用一个函数作为参数时,实际上我们就是将指定的代码传递给了目标函数
l = [1,2,3,4,5,6]
def fn(n):
if n %2 ==0:
return True
return False
def func(func,lst):
new_lst = []
for i in lst:
if fn(i)==True:
new_lst.append(i)
return new_lst
print(func(fn,l))
>>>[2, 4, 6]
filter() 可以从序列中过滤出来符合条件的元素,保存到一个新的序列当中
参数:1.函数,根据该函数来过滤序列(可迭代结构)
2. 需要过滤的序列(可迭代结构)
返回值:过滤后新的序列
l = [1,2,3,4,5,6]
def fn(n):
if n %2 ==0:
return True
return False
print(filter(fn,l))
print(list(filter(fn,l)))
>>>
>>>[2, 4, 6]
匿名函数
匿名函数 lambda表达式
lambda函数表达式是用来创建一些简单的函数 它是函数创建的另外一种方式
语法:lambda 参数列表:返回值
匿名函数最大的好处是只会调用一次,用完之后会从内存消失
匿名函数一般作为参数使用
print(lambda a,b:a+b)
>>> at 0x000001C77671DF28>
print(fn)
>>>
# 比较后 可以发现 lambda表达式创建的函数 没有名字。。
调用匿名函数
print((lambda a,b:a+b)(1,2))
>>>3
func = lambda a,b:a+b
print(func(1,2))
>>>3
再返回到filter那里
#我们用lambda表达式来替代fn函数
#因为fn函数比较简单 功能单一 且只调用一次 不会再调用 也不想让fn函数在全局作用域当中
print(list(filter(lambda i:i%2==0,l)))
>>>[2, 4, 6]
map()函数可以对 可迭代对象 中所有元素做指定的操作,然后将其添加到一个新的对象中返回
l = [1,2,3,4,5,6]
result = map(lambda i:i+1,l)
print(list(result))
>>>[2, 3, 4, 5, 6, 7]
sort()函数可以对列表当中的元素进行排序(列表对象 调用)
sort函数有一个关键字 key 需要一个函数作为参数
lst = ['e','cc','dd','bbb','aaaa']
lst.sort(key=len ) #len()函数
print(lst)
>>>['e', 'cc', 'dd', 'bbb', 'aaaa']
lst = [1,2,'3','5',0]
lst.sort(key=int) #int()函数
print(lst)
>>>[0, 1, 2, '3', '5']
sorted(_iterable,key,reverse) 会返回一个新的列表
iterable 可迭代的
reverse 反转
lst = [1,2,'3','5',0]
l = sorted(lst,key=int)
print('排序前',lst)
print('排序后',l)
>>>排序前 [1, 2, '3', '5', 0]
>>>排序后 [0, 1, 2, '3', '5']
- 闭包
将函数作为返回值返回 也是一种高阶函数
通过闭包可以创建一些只有当前函数才能访问的对象,还可以将一些私有的数据藏到闭包中
def fn():
#函数内部在定义一个函数
def fn2():
print("fn2")
#在内部函数将fn2作为返回值返回
return fn2
print(fn())
fn()()
>>>.fn2 at 0x000001710661DF28>
>>>fn2
nums = [10,10,20,30,20]
print(sum(nums)/len(nums))
>>>18.0
nums = []
def fn(num):
nums.append(num)
print(sum(nums)/len(nums))
fn(10)
fn(10)
fn(20)
fn(20)
>>>10.0
>>>10.0
>>>13.333333333333334
>>>15.0
#但是这种方式 nums为全局变量 不安全 因此引出了闭包
形成闭包的条件:
1.函数嵌套
2.将内部函数作为返回值返回
3.内部函数必须使用到外部函数的变量
什么时候使用到闭包
当你的某些数据不希望被外界访问和修改的时候 就需要用到闭包
这样能够保证数据的安全性
- 引入装饰器
def add(a,b):
print("计算开始")
r = a+b
print("计算结束")
return r
def mul(a,b):
print("计算开始")
r = a*b
print("计算结束")
print(add(1,2))
print(mul(1,2))
#我们可以通过修改函数中的代码来完成,但是会产生一些问题
#1.修改的函数很多
#2.不方便后期的维护
#3.会违背开闭原则(ocp) 程序设计 要求对程序的扩展,但是要关闭对程序的更新
下面这种写法就是对程序扩展而不更新 但是不能每调用一个方法 写一个这种函数
def add(a,b):
r = a+b
return r
def mul(a,b):
r = a*b
return r
def new_add(a,b):
print("计算开始")
r = add(a,b)
print("计算结束")
return r
print(new_add(1,2))
于是有了装饰器
def start_end(func):
def new_func(*args,**kwargs): #装包
print("程序开始")
res=func(*args,*kwargs) #解包
print("程序结束")
return res
return new_func
def add(a,b):
return a + b
def pr():
print("Hello")
print(start_end(add)(1,2))
start_end(pr)()
>>>程序开始
>>>程序结束
>>>3
>>>程序开始
>>>Hello
>>>程序结束
def start_end(func):
def new_func(*args,**kwargs): #装包
print("程序开始")
res=func(*args,*kwargs) #解包
print("程序结束")
return res
return new_func
@start_end
def add(a,b):
return a + b
print(add(1,2))
@start_end
def pr():
print("Hello")
pr()
>>>程序开始
>>>程序结束
>>>3
>>>程序开始
>>>Hello
>>>程序结束
#start_end(func) 类似这样的函数其实就是一个装饰器
#在开发中,都是通过装饰器来扩展函数的功能