浅谈Python 函数式编程
作者:认真对待世界的小白 发布时间:2022-09-03 20:38:07
匿名函数lambda表达式
什么是匿名函数?
匿名函数,顾名思义就是没有名字的函数,在程序中不用使用 def 进行定义,可以直接使用 lambda 关键字编写简单的代码逻辑。lambda 本质上是一个函数对象,可以将其赋值给另一个变量,再由该变量来调用函数,也可以直接使用。
#平时,我们是先定义函数,再进行调用
def power(x):
return x ** 2
print(power(2))
#使用lambda表达式的时候,我们可以这样操作
power = lambda x : x ** 2
print(power(2))
#觉得太麻烦,还可以这样调用
print((lambda x: 2 * x)(8))
lambda表达式的基本格式:lambda 入参 : 表达式
#入参可以有多个,比如
power = lambda x, n: x ** n
print(power(2, 3))
lambda 表达式的使用场景
一般适用于创建一些临时性的,小巧的函数。比如上面的 power函数,我们当然可以使用 def 来定义,但使用 lambda 来创建会显得很简洁,尤其是在高阶函数的使用中。
定义一个函数,传入一个list,将list每个元素的值加1
def add(l = []):
return [x +1 for x in l]
print(add([1,2,3]))
上面的函数改成将所有元素的值加2
可能大家会说,这还不简单,直接把return里的1改成2就行了。但是真的行吗?如果函数被多个地方使用,而其他地方并不想加2,怎么办?
这好办,把变得那部分抽出来,让调用者自己传
def add(func,l = []):
return [func(x) for x in l]
def add1(x):
return x+1
def add2(x):
return x+2
print(add(add1,[1,2,3]))
print(add(add2,[1,2,3]))
一个简简单单的问题,一定要用这么多代码实现?
def add(func,l = []):
return [func(x) for x in l]
print(add(lambda x:x+1,[1,2,3]))
print(add(lambda x:x+2,[1,2,3]))
map函数
map的基本格式
map(func, *iterables)
map() 函数接收两个以上的参数,开头一个是函数,剩下的是序列,将传入的函数依次作用到序列的每个元素,并把结果作为新的序列返回。也就是类似 map(func,[1,2,3])
同样的,我们还是来完成这样一个功能:将list每个元素的值加1
def add(x):
return x + 1
result = map(add, [1, 2, 3, 4])
print(type(result))
print(list(result))
使用lambda表达式简化操作
result = map(lambda x: x + 1, [1, 2, 3, 4])
print(type(result))
print(list(result))
函数中带两个参数的map函数格式
使用map函数,将两个序列的数据对应位置求和,之后返回,也就是对[1,2,3],[4,5,6]两个序列进行操作之后,返回结果[5,7,9]
print(list(map(lambda x, y: x + y, [1, 2, 3], [4, 5, 6])))
对于两个序列元素个数一样的,相对好理解。如果两个序列个数不一样的,会不会报错?
print(list(map(lambda x, y: x + y, [1, 2, 3], [4, 5])))
我们可以看到不会报错,但是结果以个数少的为准
reduce函数
reduce函数的基本格式
reduce(function, sequence, initial=None)
reduce把一个函数作用在一个序列上,这个函数必须接收两个参数,reduce函数把结果继续和序列的下一个元素做累积计算,跟递归有点类似,reduce函数会被上一个计算结果应用到本次计算中
reduce(func, [1,2,3]) = func(func(1, 2), 3)
使用reduce函数,计算一个列表的乘积
from functools import reduce
def func(x, y):
return x * y
print(reduce(func, [1, 2, 3, 4]))
结合lambda表达式,简化操作
from functools import reduce
print(reduce(lambda x, y: x * y, [1, 2, 3, 4]))
filter 函数
filter 顾名思义是过滤的意思,带有杂质的(非需要的数据),经过 filter 处理之后,就被过滤掉。
filter函数的基本格式
filter(function_or_None, iterable)
filter() 接收一个函数和一个序列。把传入的函数依次作用于每个元素,然后根据返回值是 True 还是 False 决定保留还是丢弃该元素。
使用 filter 函数对给定序列进行操作,最后返回序列中所有偶数
print(list(filter(lambda x: x % 2 == 0, [1, 2, 3, 4, 5])))
sorted 函数
sorted从字面上就可以看去这是个用来排序的函数,sorted 可以对所有可迭代的对象进行排序操作
sorted的基本格式
sorted(iterable, key=None, reverse=False)
#iterable -- 可迭代对象。
#key -- 主要是用来进行比较的元素,只有一个参数,具体的函数的参数就是取自于可迭代对象中,指定可迭代对象中的一个元素来进行排序。
#reverse -- 排序规则,reverse = True 降序 , reverse = False 升序(默认)。
#对序列做升序排序
print(sorted([1, 6, 4, 5, 9]))
#对序列做降序排序
print(sorted([1, 6, 4, 5, 9], reverse=True))
#对存储多个列表的列表做排序
data = [["Python", 99], ["c", 88]]
print(sorted(data, key=lambda item: item[1]))
闭包
在万物皆对象的Python中,函数是否能作为函数的返回值进行返回呢?
def my_power():
n = 2
def power(x):
return x ** n
return power
p = my_power()
print(p(4))
#------------------------------------------------------------
def my_power():
n = 2
def power(x):
return x ** n
return power
n = 3
p = my_power()
print(p(4))
我们可以看到,my_power 函数在返回的时候,也将其引用的值(n)一同带回,n 的值被新的函数所使用,这种情况我们称之为闭包
当我们把n的值移除到my_power函数外面,这个时候来看下计算结果
n = 2
def my_power():
def power(x):
return x ** n
return power
n = 3
p = my_power()
print(p(4))
为什么输出的结果会是64?
我们先来看看闭包时,p.__closure____的结果
#例1
def my_power():
n = 2
def power(x):
return x ** n
return power
p = my_power()
print(p.__closure__)
#结果:(<cell at 0x00000264518F9A38: int object at 0x00007FFA7F617120>)
#closure是内部函数的一个属性,用来保存环境变量
#---------------------------------------------------------------------
#例2
n = 2
def my_power():
def power(x):
return x ** n
return power
n = 3
p = my_power()
print(p.__closure__)
#输出结果 None
通过例1跟例2对比,我们可以知道,例2并不是闭包
闭包经典问题
下面的程序是否是闭包?能否正确运行
def my_power():
n = 2
def power(x):
n += 1
return x ** n
return power
p = my_power()
print(p(3))
如何让上面的程序正确运行?看看改正之后的结果
def my_power():
n = 2
def power(x):
nonlocal n
n += 1
return x ** n
return power
p = my_power()
print(p.__closure__)
print(p(3))
print(p(3))
看看下面的程序的运行结果
def my_power():
n = 2
L = []
for i in range(1, 3):
def power():
return i ** n
L.append(power)
return L
f1, f2 = my_power()
print(f1())
print(f2())
print(f1.__closure__[0].cell_contents)
print(f2.__closure__[0].cell_contents)
python的函数只有在执行时,才会去找函数体里的变量的值,也就是说你连形参都不确定,你咋求知道 i为几呢?在这里,你只需要记住如果你连形参都不确定,python就只会记住最后一个i值。
装饰器及其应用
什么是装饰器模式
装饰器模式(Decorator Pattern)允许向一个现有的对象添加新的功能,同时又不改变其结构。这种类型的设计模式属于结构型模式,它是作为现有的类的一个包装。
这种模式创建了一个装饰类,用来包装原有的类,并在保持类方法签名完整性的前提下,提供了额外的功能。
import time
start = time.time()
time.sleep(4)
end = time.time()
print(end - start)
从实际例子来看装饰器
def my_fun():
print("这是一个函数")
my_fun()
要再打印“这是一个函数”前面在打印多一行hello world。
def my_fun():
begin = time.time()
time.sleep(2)
print("这里一个函数")
end = time.time()
print(end-begin)
my_fun()
这个时候,如果不想修改原有的函数,咋整?
def my_fun():
print("这是一个函数")
def my_time(func):
begin = time.time()
time.sleep(2)
func()
end = time.time()
print(end - begin)
my_time(func)
这种方式,因为要增加功能,导致所有的业务调用方都得进行修改,此法明显不可取。
另一种方式:
def print_cost(func):
def wrapper():
begin = time.time()
time.sleep(2)
func()
end = time.time()
print(end - begin)
return wrapper
@print_cost
def my_fun():
print("这里一个函数")
第二种方式并没有修改func函数的内部实现,而是使用装饰器模式对其功能进行装饰增强。
来源:https://www.cnblogs.com/jwen1994/p/13127205.html
猜你喜欢
- 一、半同步简介MASTER节点在执行完客户端提交的事务后不是立刻返回结果给客户端,而是等待至少一个SLAVE节点接收并写到relay log
- 看看这个logo,有些像python的小蛇吧 。这次介绍的数据库codernityDB是纯python开发的。先前用了下tinyDB这个本地
- 本文实例为大家分享了Python OpenCV图像直方图和反向投影的具体代码,供大家参考,具体内容如下当我们想比较两张图片相似度的时候,可以
- 今天为大家介绍一个Python绘制一朵漂亮的玫瑰花,用python的turtle库这个绘画库是非常简单的,但是还是需要你测试路径方向,慢慢调
- 使用pix2pix-gan做医学图像合成的时候,如果把nii数据转成png格式会损失很多信息,以为png格式图像的灰度值有256阶,因此直接
- 要求:求出列表中的所有值的最大数,包括列表中带有子列表的。按照Python给出的内置函数(max)只能求出列表中的最大值,无法求出包括列表中
- 自定义查询对象 - objects①声明一个类EntryManager,继承自models.Manager,并添加自定义函数②使用创建的自定
- 这个就没什么好说的了。。直接上代码啊!! 首先是HTML的代码。其中包含了登录点击按钮以及一个简陋的登录框。 <body> &l
- 大家好,今天我在学习 MySQL 8.0.22安装及配置遇到了一些问题,特地将我整个安装过程分享出来希望可以帮助不会安装的小伙伴😜。参考链接
- #! /usr/bin/python''' File&n
- 一、 通过runtime包进行多核设置1.NumCPU()获取当前系统的cpu核数2.GOMAXPROCS设置当前程序运行时占用的cpu核数
- 目录GitHub 消息的问题解决方案代码实现0.环境准备1、模拟登录github2.模拟进入Inbox3.检查僵尸项目4.取消关注僵尸项目5
- Python编写微信小游戏“跳一跳”的运行脚本,分享给大家。更新了微信后发现了一款小游戏跳一跳,但是玩了一下午最高才达到200,每次差点破纪
- 在做js测试的时候用到了startsWith函数,但是他并不是每个浏览器都有的,所以我们一般要重写一下这个函数,具体的用法可以稍微总结一下在
- javascript的字符集:javascript程序是使用Unicode字符集编写的。Unicode是ASCII和Latin-1的超集,并
- 本文实例讲述了PHP简单检测网址是否能够正常打开的方法。分享给大家供大家参考,具体如下:这是一个检测网址是否能正常打开的PHP代码,通过下面
- 前记在Python中, Dict是一系列由键和值配对组成的元素的集合, 它是一个可变容器模型,可以存储任意类型对象. Dict的存取速度非常
- Pygame是跨平台Python模块,专为电子游戏设计,包含图像、声音。建立在SDL基础上,允许实时电子游戏研发而无需被低级语言(如机器语言
- MySQL外键约束的禁用与启用:MySQL外键约束是否启用是通过一个全局变量标示的:FOREIGN_KEY_CHECKS=0; 禁用状态FO
- 前言JS为什么要用ajax来提交在使用from提交时,浏览器会向服务器发送选中的文件的内容而不仅仅是发送文件名。为安全起见,即file-up