概念:没有名字的函数,”一句话的函数“
作用:简化代码,和其他高阶函数配合使用
语法: lambda 参数 : 表达式
**(1)无参的lambda表达式 **
func = lambda : "这是一条消息..."
#定义一个lambda表达式(匿名函数)
# 使用func变量指向这个表达式(函数)
print(func())
#有返回值
#函数式编程,更鼓励”计算过程的单纯性“,建议把”输入/输出“限制到最小
func = lambda : print("这是一条消息...")
func() #没有返回值
输出:
这是一条消息...
这是一条消息...
**(2)带参的lambda表达式 **
def add(x,y):
return x+y
print(add(1,2)) #输出结果:3
func = lambda x,y : x+y
print(func(1,2)) #输出结果:3
(3)带可变参数的lambda表达式
# **是解包操作
func=lambda **kw:print(f"{kw}")
func(id=1,city="长沙")
func=lambda *argc,**kwargs:print(f"{argc},{kwargs}")
func(1,2,3,4,5,id=100,city="长沙")
输出:
{'id': 1, 'city': '长沙'}
(1, 2, 3, 4, 5),{'id': 100, 'city': '长沙'}
概念:把函数当成参数传递的函数就是高阶函数。
def printInfo(): #定义了一个函数
print("info.....")
printInfo() #输出结果:info.....
#高阶函数
def runFunc(func):
func() #调用传入的函数 # 相当于调用了printInfo()
runFunc(printInfo) #将函数作为参数值,括号中仅仅是函数名
输出结果:info.....
语法:map(function, iterable, …)
功能:把可迭代对象中的数据逐一拿出来,经过函数处理之后,将结果放到迭代器中并返回迭代器。
参数:
比如下面,将给定的字符串列表转换为整数列表
li=["1","2","3","4","5"]
res=map(int,li)
for i in res:
print(i,end=" ")
print("")
print(list(li))
输出:
1 2 3 4 5
['1', '2', '3', '4', '5']
自定义函数
求字符串列表所表达数值的平方
li=["1","2","3","4","5"]
def getsquare(x):
return int(x)**2
#map的返回值是一个迭代器对象
res=map(getsquare,li)
print(list(res))
输出:[1, 4, 9, 16, 25]
使用lambda表达式
l1 = ["1","2","3","4"]
res = map(lambda x:int(x)**2,l1) #体现出了匿名函数的特点
print("lambda表达式:",list(res))
输出结果:lambda表达式: [1, 4, 9, 16]
多个可迭代对象作为参数
l1 = [1,2,3,4]
l2 = [5,6,7,8]
# 分别获取两个迭代对象的元素,作为lambda表达式的参数
res = map(lambda x,y: x+y,l1,l2 )
print(list(res))
输出:[6, 8, 10, 12]
应用案例:
将下面的字典进行键值对互换:
dic = {“北京”:“京”,“上海”:“沪”,“广东”:“粤”,“四川”:“川”}
dic = {"北京":"京","上海":"沪","广东":"粤","四川":"川"}
def change(item):
return (item[1],item[0])
res=map(change,dic.items())
print(dict(res))
lambda表达式写法
res=map(lambda item:(item[1],item[0]),dic.items())
print(dict(res))
输出:{'京': '北京', '沪': '上海', '粤': '广东', '川': '四川'}
语法: reduce(function, sequence[, initial]) -> value
功能:给定序列,依次取出1个元素作为参数,与前一次函数结果进行函数运算,最后返回运算结果
参数:
**实现列表元素相乘 **
obj = [“1”,“2”,“3”,“4”,“5”]
from functools import reduce
obj = ["1","2","3","4","5"]
def multi(x,y):
return int(x)*int(y)
res=reduce(multi,obj)
print(int(res))
输出:120
使用lambda表达式
res=reduce(lambda x,y:int(x)*int(y),obj)
print(int(res))
输出:120
语法:filter(func,iterable) -> iterator
功能:过滤数据
如果函数的返回值是True,代表保留当前数据
如果函数的返回值是False,代表舍弃当前数据
参数:
保留列表的偶数
lst = [1,2,3,4,21,32,43,54]
res=filter(lambda x: True if x%2==0 else False, lst)
print(list(res))
输出:[2, 4, 32, 54]
语法:sorted(iterable,reverse=False,key=函数) -> Iterator
功能:排序
参数:
iterable: 可迭代对象(常用:容器类型数据,range对象,迭代器)
reverse: 是否倒序
按照余数的大小进行排序
lst = [20,31,47,19,15]
def k(x):
return x%3
res1=sorted(lst,reverse=False,key=k)
res2=sorted(lst,key=lambda x:x%3)
print(res1)
print(res2)
输出:
[15, 31, 19, 20, 47]
[15, 31, 19, 20, 47]
函数返回值也可以是函数
def food(name): #外函数
def prepare(): #内函数
print(f"[{name}]制作步骤:备菜...") #内部函数可以使用外部函数的变量
def cook():
print(f"[{name}]制作步骤:烹饪...")
def serve():
prepare()
cook()
print(f"[{name}]制作步骤:上菜!")
return serve
m = food("番茄炒蛋")
f = food("小鸡炖蘑菇")
f()
m()
输出:
[小鸡炖蘑菇]制作步骤:备菜...
[小鸡炖蘑菇]制作步骤:烹饪...
[小鸡炖蘑菇]制作步骤:上菜!
[番茄炒蛋]制作步骤:备菜...
[番茄炒蛋]制作步骤:烹饪...
[番茄炒蛋]制作步骤:上菜!
返回多个函数值
def food(name): #外函数
def prepare(): #内函数
print(f"[{name}]制作步骤:备菜...") #内部函数可以使用外部函数的变量
def cook():
print(f"[{name}]制作步骤:烹饪...")
def serve():
prepare()
cook()
print(f"[{name}]制作步骤:上菜!")
return (prepare,cook,serve)
m = food("番茄炒蛋")
m[0]()
m[1]()
输出:
[番茄炒蛋]制作步骤:备菜...
[番茄炒蛋]制作步骤:烹饪...
概念:内函数使用了外函数的局部变量,并且外函数把内函数返回出来的过程叫做闭包,这个内函数叫做闭包函数。
闭包函数用法
def outer():
a = 5
def inner(): #闭包函数
print(a) #通过使用外部函数的变量,延长了变量的使用时间
return inner
func = outer() #外部函数调用后,返回内部函数的地址
func() #通过内部函数的地址,完成内部函数调用
输出结果:5
下面说明一个闭包函数的使用场景
#test函数中的a,b参数不经常变化,
#内部函数test_in中的参数c每次调用都需要重新赋值
def test(a,b,c):
print(a*b+c)
test(1,1,2)
test(1,1,3)
test(3,5,2)
test(3,5,3)
输出:3 4 17 18
下面可以使用闭包函数降低函数调用的负责程度
def test(a,b):
def test_in(c):
print(a*b+c)
return test
num = test(1,1)
num(2)
num(3)
print("-"*30)
num_02 = test(2,2)
num_02(2)
num_02(3)
num(6)
输出:
3
4
------------------------------
6
7
7
功能:不改变现有函数的前提下,扩展函数功能
语法:使用@符号
在执行函数前,要先执行装饰器
原写法的目的
def checkon(func):
def checklog():
print("函数运行前,进行权限的校验")
func()
print("函数运行后,进行日志记录")
return checklog
def printinfo():
print("我是一个普通的函数")
newfunc=check(printinfo)
newfunc()
输出结果:
函数运行前,进行权限的校验
我是一个普通的函数
函数运行后,进行日志记录
装饰器的写法
def checkon(func):
def checkAndLog():
print("函数运行前,进行权限的校验")
func()
print("函数运行后,进行日志记录")
return checkAndLog
@checkon #定义装饰器的位置,相当于checkon(printInfo)
def printInfo():
print("我是一个普通的函数")
@checkon
def test():
print("test.....")
printInfo()
test()
两个及多个装饰器可以装饰同一个函数。
执行的过程为:自下而上逐步修饰,完成后一次性输出。
def zsA(func):
def resFunc():
print("zsA执行前...")
func()
print("zsA执行后...")
return resFunc
def zsB(func):
def resFunc():
print("zsB执行前...")
func()
print("zsB执行后...")
return resFunc
@zsB
@zsA #自下而上逐步修饰,完成后一次性输出
def test():
print("这是测试函数")
test()
#相当于:
res1 = zsA(test)
res2 = zsB(res1)
res2()
输出结果:
zsA执行前...
zsB执行前...
zsA执行前...
这是测试函数
zsA执行后...
zsB执行后...
zsA执行后...
zsB执行后...
如果原函数带有参数,那么返回的新函数也要带有参数,且参数一一对应
def tool(func):
def log(name,pwd):
print(f"日志记录:【{name}:{pwd}】")
func(name,pwd)
return log
@tool
def login(name,pwd):
print(f"用户名:{name},密码:{pwd}")
login("admin",123456)
相当于:
# res = tool(login)
# res("admin",123456)
输出:
日志记录:【admin,123456】
用户名:admin,密码:123456
如果原函数带有返回值,装饰器也要有返回值,才能将原有函数的执行结果传递出来 。
def tool(func):
def log(name,pwd):
print(f"日志记录:【{name}:{pwd}】")
state = func(name,pwd)
return state
return log
@tool
def login(name,pwd):
print(f"用户名:{name},密码:{pwd}")
if name == "admin" and pwd == 123456:
return "登录成功"
return "登录失败"
res = login("admin",12345678)
print(res)
相当于:
rt=tool(login)
rt("admin,12345678")
日志记录【admin,12345678】
用户名:admin,密码:12345678
#return 登录失败
登录失败
增加装饰器的适用性,可以使用可变参数,以保证装饰器能够适用于更多的函数
def tool(func):
def log(*args,**kwargs):
print(f"日志记录前。。。")
state = func(*args,**kwargs)
print(f"日志记录后。。。")
return state
return log
@tool
def test():
print("test....")
@tool
def login(name,pwd):
print(f"用户名:{name},密码:{pwd}")
if name == "admin" and pwd == 123456:
return "登录成功"
return "登录失败"
test()
res = login("admin",12345678)
print(res)
输出结果:
日志记录前。。。
test....
日志记录后。。。
日志记录前。。
用户名:admin,密码:12345678
日志记录后。。。
登录失败