python采用函数编程模式_浅谈Python 函数式编程

匿名函数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__)

#结果:()

#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函数的内部实现,而是使用装饰器模式对其功能进行装饰增强。

以上就是浅谈Python 函数式编程的详细内容,更多关于Python 函数式编程的资料请关注python博客其它相关文章!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/335980.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【安卓开发 】Android初级开发(一)控件通用属性

控件通用属性 match_parent 是指和父容器宽高相等的值,其他的同理可证。 android:layout_marginTop"XXXXXXdp" 距离顶部的距离 Android TextView属性详解 该控件相关属性 Android EditText属性大全 相关属性查看地址 事件监听处理 package com.examp…

dynamodb java_使用Java将项目插入DynamoDB表

dynamodb java在上一篇文章中,我们学习了如何使用Java创建DynamoDB表。 下一步是将项目插入到先前创建的DynamoDB表中。 请记住,对于插入操作,最基本的步骤是指定主键。 对于表用户,主键是属性电子邮件。 您可以根据需要添加任意…

成都python数据分析师职业技能_数据分析师需要什么技能,数据分析行业都有什么职业?...

就目前而言,很多人看到了数据分析行业的光明前景,于是就想进入数据分析的行业中,但是,想成为一名合格的数据分析师,需要掌握很多的技能,那么一名合格的数据分析师需要掌握哪些技能呢?现在的数据…

【安卓开发 】Android初级开发(零)各种布局

线性布局的重要属性 (LinearLayout) 相关属性链接 layout_width 和 layout_height是布局器相对于外部构件的一个宽高距离。 layout_margin是指与外部控件的整个边缘距离。 padding是指与控件的内边距离 android:orientation 方向作用于整个布局中的所有控件 android:layo…

jboss fuse 教程_JBoss Fuse:使用JEXL的动态蓝图文件

jboss fuse 教程在本文中,我将展示如何在Apache Aries Blueprint xml文件中添加一些内联脚本。 我不一定会称其为最佳实践,但我一直有这样的想法:这种能力可能有用。 可能当我被迫使用xml来模拟命令式编程结构(例如使用Apache An…

认证令牌_Java应用程序的令牌认证

认证令牌建筑物身份管理,包括身份验证和授权? 尝试Stormpath! 我们的REST API和强大的Java SDK支持可以消除您的安全风险,并且可以在几分钟内实现。 注册 ,再也不会建立auth了! 2016年5月12日更新&#xf…

java package报错_Java基础知识总结 - 超详细篇(上)

1,JDK:Java Development Kit,java的开发和运行环境,java的开发工具和jre。2,JRE:Java Runtime Environment,java程序的运行环境,java运行的所需的类库JVM(java虚拟机)。3&#xff0c…

【安卓开发 】Android初级开发(二)Activity启动模式

Activity页面跳转在业务逻辑页面添加以下代码 //跳转到下一个activityIntent intent new Intent(this,MainActivity2.class);startActivity(intent); Activity四种启动模式 具体链接

weblogic 建立websocket连接报404_基于 Serverless 与 Websocket 的聊天工具实现

传统业务实现 Websocket 并不难,然而函数计算基本上都是事件驱动,不支持长链接操作。如果将函数计算与 API 网关结合,是否可以有 Websocket 的实现方案呢?API 网关触发器实现 WebsocketWebSocket 协议是基于 TCP 的一种新的网络协…

java的默认值规则_Java 8:默认方法解析规则

java的默认值规则随着Java 8中默认方法的引入,一个类现在可以从多个位置(例如另一个类或接口)继承相同的方法。 在这种情况下,可以使用以下规则来确定选择哪种方法: 类或超类方法声明始终优先于默认方法 否则&#x…

【Android OpenGL ES 开发 (五)】纹理相关(二)

纹理放大和缩小的过滤参数 1.使用线性插值效果最佳 2.通过修改 float maxscale 4.0f //放大 float minscale 0.5f //缩小 vertices[0].mPosition[0]0.5f * maxscale; //x vertices[0].mPosition[1]0.5f * maxscale; //y 实现模糊效果 1.利用显卡的并行计算的强大功能对…

python与sqlite3_sqlite3与python2.5,pysqlite和apsw有什么区别

我想知道python2.5,pysqlite和apsw的sqlite3之间的区别?当我尝试使用python2.5在windows vista上安装pysqlite时,我有一个颠簸的运行,请参阅以下内容:>从http://sqlite.org/download.html下载sqlite并将它们解压缩到windows / system32文件夹并将sqli…

monolith_将Java EE Monolith雕刻成微服务

monolith在介绍了为什么微服务应该由事件驱动的简介博客之后,我想采取一些其他步骤,并在有关博客的同时准备我即将进行的一系列演讲(在jBCNconf和Red Hat Summit上与您见面) 。旧金山 )。 在Twitter christianposta上关…

【H.264/AVC视频编解码技术】第四章【SPS序列参数集】

1.H264码流中重要的组成部分,保存针对整个视频序列的参数,丢失SPS的码流通常无法正常解码。 2.SPS信息的保存位置: 封装格式: FLV======会保存在 Tag中的Video Tag Data 部分,会有AVC VIDEO PACKET结构。SPS就包含在其中。 MP4===== H264裸码流: 保存…

spring内容协商管理_Spring框架中的内容协商

spring内容协商管理1.简介 使用BeanNameViewResolver完成的工作就是,我们刚刚在Spring上下文中创建了多个bean视图以生成预期的输出。 Spring很快引入了内容协商策略 ,该策略可以使用传统的RESTful ResponseBody方法和HTTP消息转换器,以JSON或…

二叉树专题

二叉树 (一)二叉树的三种遍历方式: 前序遍历 : 1 2 4 5 3 6 7 ; 中序遍历 : 4 2 5 1 6 3 7 ; 后序遍历 : 4 5 2 6 7 3 1 ; 本质是在递归序的基础上…

echart中拆线点的偏移_Real BIM | Rhino+Grasshopper在双曲异形玻璃幕墙中的应用

转载请联系并注明来源你好,我以自己所做的项目为例,介绍一下我的认知里,BIM技术对于真实项目的作用。案例是一个异形、双曲面的玻璃屋盖幕墙系统。如效果图所示,玻璃屋盖呈波浪状,塔楼装饰条与屋盖装饰条需要无缝连接。…

【安卓开发】Android初级开发(okhttp3发送带header与带参数的GET请求)

1.首先需要先加入相应依赖 dependencies{implementation com.squareup.okhttp3:okhttp:3.13.1 implementation com.squareup.okio:okio:2.2.2} 2.加入互联网权限 <!-- 互联网 --><uses-permission android:name"android.permission.INTERNET" /> <!…

java 文件保存在内存_如何掌握Java内存(并保存程序)

java 文件保存在内存通过AppDynamics解决应用程序问题的速度提高了10倍–以最小的开销在代码级深度监视生产应用程序。 开始免费试用&#xff01; 您花费了无数小时来解决Java应用程序中的错误并在需要的地方获得其性能。 在测试过程中&#xff0c;您注意到应用程序随着时间的…

sql 返回日期的年月部分_公示|2020年11月部分志愿活动名单公示

2020年11月部分志愿活动名单公示2020年11月18日人文与法学学院院楼协助分发教职工运动会服装志愿活动2020年11月19日人文与法学学院院楼“收彩旗”志愿活动2020年11月20日人文与法学学院组织观看2020年全国科学道德和学风建设宣讲教育报告会直播志愿活动(此活动不录入i志愿)202…