【Python】函数式编程

发布于:2022-12-22 ⋅ 阅读:(338) ⋅ 点赞:(0)

1.lambda表达式

概念:没有名字的函数,”一句话的函数“
作用:简化代码,和其他高阶函数配合使用
语法: 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': '长沙'}

2.高阶函数

概念:把函数当成参数传递的函数就是高阶函数。

def printInfo(): 	#定义了一个函数
	print("info.....")
printInfo() #输出结果:info.....


#高阶函数
def runFunc(func): 
	func() 			#调用传入的函数 # 相当于调用了printInfo()
runFunc(printInfo) #将函数作为参数值,括号中仅仅是函数名


输出结果:info.....

2.1map

语法:map(function, iterable, …)
功能:把可迭代对象中的数据逐一拿出来,经过函数处理之后,将结果放到迭代器中并返回迭代器。
参数:

  • func: 自定义函数 或者 内置函数
  • iterable: 可迭代对象(常用:容器类型数据,range对象,迭代器)
  • 返回值:迭代器

比如下面,将给定的字符串列表转换为整数列表

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))

输出:{'京': '北京', '沪': '上海', '粤': '广东', '川': '四川'}

2.2reduce

语法: reduce(function, sequence[, initial]) -> value
功能:给定序列,依次取出1个元素作为参数,与前一次函数结果进行函数运算,最后返回运算结果
参数:

  • func 自定义函数 或者 内置函数
  • iterable 可迭代对象(常用:容器类型数据 range对象 迭代器)
  • 返回值:最终的计算结果

**实现列表元素相乘 **

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

2.3filter

语法:filter(func,iterable) -> iterator
功能:过滤数据
如果函数的返回值是True,代表保留当前数据
如果函数的返回值是False,代表舍弃当前数据
参数:

  • func 自定义函数
  • iterable 可迭代对象(常用:容器类型数据,range对象,迭代器)
  • 返回值:迭代器

保留列表的偶数

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]

2.4sorted函数

语法:sorted(iterable,reverse=False,key=函数) -> Iterator
功能:排序
参数:
iterable: 可迭代对象(常用:容器类型数据,range对象,迭代器)
reverse: 是否倒序

  • 默认正序reverse=False(从小到大)如果reverse=True 代表倒序(从大到小)
  • key = 自定义函数 或者 内置函数
  • 返回值:排序的序列

按照余数的大小进行排序

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]

2.5返回函数

函数返回值也可以是函数

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]()

输出:
[番茄炒蛋]制作步骤:备菜...
[番茄炒蛋]制作步骤:烹饪...

2.6闭包函数

概念:内函数使用了外函数的局部变量,并且外函数把内函数返回出来的过程叫做闭包,这个内函数叫做闭包函数。

闭包函数用法

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
  • 闭包,构建了类似面向对象中“类”的形式,目的是为了实现:“数据的封装”
  • 内部函数可以使用外部函数定义的属性,“多个外部函数”的内部函数不能相互共享数据
  • 类似于:**每个外部函数调用时,开辟一块新的内存空间;每个内存空间中的属性和内部函数有绑定关系

3.装饰器

功能:不改变现有函数的前提下,扩展函数功能
语法:使用@符号

在执行函数前,要先执行装饰器

原写法的目的
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()

3.1装饰器嵌套

两个及多个装饰器可以装饰同一个函数。
执行的过程为:自下而上逐步修饰,完成后一次性输出。

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执行后...

3.2带参数的装饰器

如果原函数带有参数,那么返回的新函数也要带有参数,且参数一一对应

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

3.3带返回值的装饰器

​ 如果原函数带有返回值,装饰器也要有返回值,才能将原有函数的执行结果传递出来 。

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 登录失败
登录失败

3.4通用模板参数

​ 增加装饰器的适用性,可以使用可变参数,以保证装饰器能够适用于更多的函数

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
日志记录后。。。
登录失败
本文含有隐藏内容,请 开通VIP 后查看

网站公告

今日签到

点亮在社区的每一天
去签到