• 【Python】函数式编程


    1.lambda表达式

    概念:没有名字的函数,”一句话的函数“
    作用:简化代码,和其他高阶函数配合使用
    语法: lambda 参数 : 表达式

    **(1)无参的lambda表达式 **

    func = lambda : "这是一条消息..." 
    #定义一个lambda表达式(匿名函数)
    # 使用func变量指向这个表达式(函数)
    print(func())
    #有返回值
    #函数式编程,更鼓励”计算过程的单纯性“,建议把”输入/输出“限制到最小
    func = lambda : print("这是一条消息...")
    func() #没有返回值
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    输出:
    
    这是一条消息...
    这是一条消息...
    
    • 1
    • 2
    • 3
    • 4

    **(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
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    (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="长沙")
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    输出:
    
    {'id': 1, 'city': '长沙'}
    (1, 2, 3, 4, 5),{'id': 100, 'city': '长沙'}
    
    • 1
    • 2
    • 3
    • 4

    2.高阶函数

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

    def printInfo(): 	#定义了一个函数
    	print("info.....")
    printInfo() #输出结果:info.....
    
    
    #高阶函数
    def runFunc(func): 
    	func() 			#调用传入的函数 # 相当于调用了printInfo()
    runFunc(printInfo) #将函数作为参数值,括号中仅仅是函数名
    
    
    输出结果:info.....
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    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
    • 6
    • 7
    输出:
    1 2 3 4 5 
    ['1', '2', '3', '4', '5']
    
    • 1
    • 2
    • 3

    自定义函数

    求字符串列表所表达数值的平方

    li=["1","2","3","4","5"]
    
    def getsquare(x):
        return int(x)**2
    #map的返回值是一个迭代器对象
    res=map(getsquare,li)
    print(list(res))
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    输出:[1, 4, 9, 16, 25]
    
    • 1

    使用lambda表达式

    l1 = ["1","2","3","4"]
    res = map(lambda x:int(x)**2,l1) #体现出了匿名函数的特点
    print("lambda表达式:",list(res)) 
    
    输出结果:lambda表达式: [1, 4, 9, 16]
    
    • 1
    • 2
    • 3
    • 4
    • 5

    多个可迭代对象作为参数

    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]
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    应用案例:

    将下面的字典进行键值对互换:
    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))
    
    输出:{'京': '北京', '沪': '上海', '粤': '广东', '川': '四川'}
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    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
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    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]
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    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]
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    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()
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    输出:
    [小鸡炖蘑菇]制作步骤:备菜...
    [小鸡炖蘑菇]制作步骤:烹饪...
    [小鸡炖蘑菇]制作步骤:上菜!
    [番茄炒蛋]制作步骤:备菜...
    [番茄炒蛋]制作步骤:烹饪...
    [番茄炒蛋]制作步骤:上菜!
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    返回多个函数值

    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]()
    
    输出:
    [番茄炒蛋]制作步骤:备菜...
    [番茄炒蛋]制作步骤:烹饪...
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    2.6闭包函数

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

    闭包函数用法

    def outer():
    	a = 5
    	def inner(): #闭包函数
    		print(a) #通过使用外部函数的变量,延长了变量的使用时间
    	return inner
    func = outer() #外部函数调用后,返回内部函数的地址
    func() #通过内部函数的地址,完成内部函数调用
    
    输出结果:5
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    下面说明一个闭包函数的使用场景

    #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
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    下面可以使用闭包函数降低函数调用的负责程度

    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
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 闭包,构建了类似面向对象中“类”的形式,目的是为了实现:“数据的封装”
    • 内部函数可以使用外部函数定义的属性,“多个外部函数”的内部函数不能相互共享数据
    • 类似于:**每个外部函数调用时,开辟一块新的内存空间;每个内存空间中的属性和内部函数有绑定关系

    3.装饰器

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

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

    原写法的目的
    def checkon(func):
        def checklog():
            print("函数运行前,进行权限的校验")
        	func()
            print("函数运行后,进行日志记录")
         return checklog
    def printinfo():
        print("我是一个普通的函数")
    
    newfunc=check(printinfo)
    newfunc()
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    输出结果:
    	函数运行前,进行权限的校验
    	我是一个普通的函数
    	函数运行后,进行日志记录
    
    • 1
    • 2
    • 3
    • 4

    装饰器的写法

    def checkon(func):
        def checkAndLog():
            print("函数运行前,进行权限的校验")
            func()
            print("函数运行后,进行日志记录")
        return checkAndLog
    
    @checkon			#定义装饰器的位置,相当于checkon(printInfo)
    def printInfo():
        print("我是一个普通的函数")
    @checkon
    def test():
        print("test.....")
    
    printInfo()
    test()
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    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()
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    输出结果:
    	zsA执行前...
    	zsB执行前...
    	zsA执行前...
    	这是测试函数
    	zsA执行后...
    	zsB执行后...
    	zsA执行后...
    	zsB执行后...
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    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
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    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 登录失败
    登录失败
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    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)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    输出结果:
    日志记录前。。。
    test....
    日志记录后。。。
    日志记录前。。
    用户名:admin,密码:12345678
    日志记录后。。。
    登录失败
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
  • 相关阅读:
    年薪30w项目经理都在用的6个项目管理软件
    146. LRU 缓存
    PaxCompiler语言的编译器
    SaaSpace:4种最佳硬盘恢复软件工具
    程序人生:技术水平低,就这还敢写自动化项目实战经验丰富?
    了解mysql脏页落盘过程
    四、综合——通信系统
    kali中解压缩文件包命令大全
    Ruby on Rails 实践:课程导读
    Centos下部署CodiMD
  • 原文地址:https://blog.csdn.net/qq_53893431/article/details/126801204