10分钟学会python函数式编程(函数 python)
off999 2024-09-26 16:18 38 浏览 0 评论
欢迎点击右上角关注小编,除了分享技术文章之外还有很多福利,私信学习资料可以领取包括不限于Python实战演练、大航海计划、BAT内推、学习资料等。
在这篇文章里,你将学会什么是函数范式以及如何使用Python进行函数式编程。你也将了解列表推导和其它形式的推导。
函数范式
在命令式范式中,通过为计算机提供一系列指令然后执行它们来完成任务。在执行这些指令时,可以改变某些状态。例如,假设你最初将A设置为5,然后更改A的值。这时在变量内部值的意义上,你改变了A的状态。
在函数式范式中,你不用告诉计算机做什么而是告诉他这个东西是什么。比如数字的最大公约数是什么,从1到n的乘积是什么等等。
因此,变量不能变化。一旦你设置了一个变量,它就永远保持这种状态(注意,在纯函数式语言中,它们不是变量)。因此,函数式编程没有副作用。副作用指的是函数改变它自己以外的东西。让我们看一些典型Python代码的示例:
这段代码的输出是5。在函数式范式中,改变变量是一个很大的禁忌,并且具有影响其范围之外事物的功能也是一个很大的禁忌。函数唯一能做的就是计算一些东西并将其作为结果返回。
现在你可能会想:“没有变量,没有副作用?为什么这样好?“这个问题问得好,我相信大多数人对此感到疑惑。
如果使用相同的参数调用函数两次,则保证返回相同的结果。如果你已经学习了数学函数,你就会知道这个好处。这称为参照透明度。由于函数没有副作用,如果你正在构建一个计算某些事情的程序,你可以加速程序。如果每次调用func(2)都返回3,我们可以将它存储在表中,这可以防止程序重复运行相同的功能。
通常,在函数式编程中,我们不使用循环。我们使用递归。递归是一个数学概念,通常意味着“自我调用”。使用递归函数,该函数将其自身作为子函数重复调用。这是Python中递归函数的一个很好的例子:
在学习中有迷茫不知如何学习的朋友小编推荐一个学Python的学习q u n 227 -435- 450可以来了解一起进步一起学习!
有些编程语言也具有惰性。这意味着他们直到最后一秒才计算或做任何事情。如果你编写一些代码来执行2 + 2,函数程序只会在你真正需要使用结果时计算出来。我们很快就会在Python中探索惰性。
Map
为了理解,我们先来看看迭代是什么。通常可以迭代的对象是列表或数组,但Python有许多不同的类型可以迭代。你甚至可以创建自己的对象,这些对象可以通过实现魔术方法进行迭代。魔术方法就像是一个API,可以帮助你的对象变得更加Pythonic。您需要实现2个魔术方法才能使对象成为可迭代的:
第一个魔术方法“__iter__”(注:这里是双下划线)返回迭代对象,这通常在循环开始时使用。”__next__“返回下一个对象。
让我们快速进入一个终端调用上面的代码:
运行将会打印出
在Python中,迭代器是一个只有__iter__魔术方法的对象。这意味着您可以访问对象中的位置,但不能遍历该对象。一些对象将具有魔术方法__next__而不是__iter__魔术方法,例如集合(在本文后面讨论)。对于本文,我们假设我们接触的所有内容都是可迭代的对象。
现在我们知道什么是可迭代对象了,让我们回到map函数。 map函数允许我们将函数应用于iterable中的每一项。 Map需要2个输入,它们分别是要应用的函数和可迭代对象。
假设我们有一个数字列表,如下所示:
我们想要对每个数字进行平方,我们可以编写如下代码:
Python中函数式的函数是具有惰性的。如果我们不使用“list”,该函数将存储iterable的定义,而不是列表本身。我们需要明确告诉Python“把它变成一个列表”供我们使用。
在Python中突然从非惰性求值转向惰性求值有点奇怪。如果你在函数式思维方式中考虑得更多,而不是命令式思维方式,那么你最终会习惯它。
现在写一个像“square(num)”这样的普通函数虽然很好,但却是不对的。我们必须定义一个完整的函数才能在map中使用它?好吧,我们可以使用lambda(匿名)函数在map中定义一个函数。
Lambda表达式
lambda表达式是一个只有一行的函数。举个例子,这个lambda表达式对给定的数字进行平方:
让我们运行它:
这看起来不像一个函数吗?
嗯,这有点令人困惑,但可以解释。我们将一些东西分配给变量“square”。那这个呢:
告诉Python这是一个lambda函数,输入叫做x。冒号之后的任何内容都是您对输入所做的操作,它会自动返回结果。
简化我们的square程序到只有一行代码,我们可以这样做:
所以在lambda表达式中,所有参数都在左边,你要用它们做的东西在右边。它有点乱。但事实是,编写只有其他函数式程序员才能阅读的代码会有一定的乐趣。此外,使用一个函数并将其转换为一行代码是非常酷的。
Reduce
Reduce是一个将迭代变成一个东西的函数。通常,你可以在列表上使用reduce函数执行计算以将其减少到一个数字。 Reduce看起来像这样:
我们经常会使用lambda表达式作为函数。
列表的乘积是每个单独的数字相乘。要做到这一点你将编写如下代码:
但是使用reduce你可以这样写:
获得相同的功能,代码更短,并且在使用函数式编程的情况下更整洁。(注:reduce函数在Python3中已不是内置函数,需要从functools模块中导入)
Filter
filter函数采用可迭代的方式,并过滤掉你在该可迭代中不需要的所有内容。
通常,filter需要一个函数和一个列表。它将函数应用于列表中的每一项,如果该函数返回True,则不执行任何操作。如果返回False,则从列表中删除该项。
语法如下:
让我们看一个小例子,没有filter我们会写:
使用filter,可以这样写:
高阶函数
高阶函数可以将函数作为参数并返回函数。一个非常简单的例子如下:
第二个返回函数的例子:
开头我说过纯函数式编程语言没有变量。更高阶的函数使这变得更容易。
Python中的所有函数都是一等公民。一等公民被定义为具有以下一个或多个特征:
在运行时创建
在数据结构中分配变量或元素
作为函数的参数传递
作为函数的结果返回
Python中的所有函数都可以用作高阶函数。
Partial application
Partial application(也称为闭包)有点奇怪,但非常酷。您可以在不提供所需的所有参数的情况下调用函数。让我们在一个例子中看到这一点。我们想要创建一个函数,它接受2个参数,一个基数和一个指数,并返回指数幂的基数,如下所示:
现在我们想要一个专用的平方函数,使用幂函数计算出数字的平方:
这有效,但如果我们想要一个立方体功能呢?或者求四次方的功能呢?我们可以继续写下它们吗?好吧,你可以。但程序员很懒的。如果你一遍又一遍地重复同样的事情,这表明有一种更快的方法来加快速度,这将使你不再重复。我们可以在这里使用闭包。让我们看一个使用闭包的square函数的示例:
是不是很酷!我们可以只使用1个参数来调用需要2个参数的函数。
我们还可以使用一个循环来生成一个幂函数,该函数实现从立方体一直到1000的幂。
函数式编程不是pythonic
您可能已经注意到了,我们想要在函数式编程中做的很多事情都围绕着列表。除了reduce函数和闭包之外,您看到的所有函数都会生成列表。 Guido(Python之父)不喜欢Python中的函数式,因为Python已经有了自己生成列表的方法。
如果你在Python的交互环境下写入”import this“,你将会得到:
这是Python之禅。这是一首关于Pythonic意味着什么的诗。我们想要涉及的部分是:
There should be one — and preferably only one — obvious way to do it.(应该尽量找到一种,最好是唯一一种明显的解决方案)
在Python中,map和filter可以执行与列表推导(下面讨论)相同的操作。这打破了Python之禅的一个规则,因此函数式编程的这些部分不被视为“pythonic”。
另一个话题是Lambda。在Python中,lambda函数是一个普通函数。 Lambda是语法糖。这两种说法是等价的。
普通函数可以执行lambda函数可以执行的所有操作,但它不能以相反的方式工作。 lambda函数不能完成普通函数可以执行的所有操作。
这是一个简短的论证,为什么函数式编程不能很好地适应整个Python生态系统。你可能已经注意到我之前提到了列表推导,我们现在将讨论它们。
列表推导
前面,我提到过你可以用map或filter做的任何事情,你可以用列表推导。列表推导是一种在Python中生成列表的方法。语法是:
让我们对列表中的每个数字进行平方,例如:
我们可以看到如何将函数应用于列表中的每一项。我们如何应用filter呢?看看前面的代码:
我们可以将其转换成一个列表推导,像这样:
列表支持if这样的语句。您不再需要将一百万个函数应用于某些东西以获得您想要的东西。事实上,如果你想尝试生成某种列表,那么使用列表推导看起来会更清晰,更容易。如果我们想要将列表中每个0以下的数字平方怎么办?有了lambda,map和filter你会写:
这似乎很长很复杂。通过列表推导,它只是:
列表推导仅适用于列表。map,filter适合任何可迭代的对象,那么这有什么用呢?你可以对你遇到的任何可迭代对象使用任何推导。
其他推导
你可以为任何可迭代对象创建一个推导。
可以使用推导生成任何可迭代的对象。从Python 2.7开始,您甚至可以生成字典(hashmap)。
如果它是可迭代的,则可以生成它。让我们看一下最后一组的例子。
set是一个元素列表,在该列表中没有元素重复两次。
set中的元素没有顺序。
您可能会注意到set(集合)与dict(字典)具有相同的花括号。 Python非常聪明。根据你是否为dict提供值,它会知道你是在写dict推导还是set推导。
总结
函数式编程美观而纯粹。函数式代码可以很干净,但也可能很乱。一些Python程序员不喜欢Python中的函数式编程。但我认为,你应该在解决问题时,使用最佳工具。10分钟学会python函数式编程
相关推荐
- 如何设置本地连接
-
在“控制面板”中,选择“网络和Internet”>“网络和共享中心”。在左侧窗格中,选择“更改适配器设置”。在“网络连接”窗口中,右键单击“本地连接”,然后选择“属性”。在“本地连接...
- 戴尔官网官方网站(戴尔产品官网)
-
查询步骤如下:1.在戴尔电脑的后盖上找到服务编号,并记录下来。2.之后搜索戴尔官网,在打开的官网界面中点击上方的支持选项,并点击产品支持。3.在打开的产品支持界面中,输入电脑后盖上的服务编号。4.如果...
- 黑鲨u盘重装系统教程(黑鲨u盘重装系统步骤8)
-
U盘重装WIn10系统:1、用【u深度u盘启动盘制作工具】制作u盘启动盘,插入电脑usb接口,设置好开机启动项进入u深度主菜单界面,选择“【02】u深度win8pe标准版(新机器)”并回车,2、在u深...
- 电子邮件免费注册入口(电子邮件在线注册)
-
1.在网页上搜索maiI163邮箱登录,如果有邮箱账号密码的话就直接输入并点击“登录”,没有的话就点击“立即注册”。2.点击“立即注册”后进入页面,输入信息点击“注册”。3.注册成功后就直接搜索登录。...
-
- win7如何快速启动(windows7如何快速启动)
-
打开操作系统运行:输入"cmd"并点击回车:系统命令提示符自动打开:使用方法直接运行start打开一个新的命令提示符窗口:运行start+文件的绝对存储路径打开对应的文件:运行start+文件夹路径打开对应...
-
2025-12-29 13:03 off999
- 怎么升级到win11(怎么升级到win11专业版)
-
Windows11可以在「开始菜单-设置-Windows更新」中进行手动更新。如果您想主动更新,需先确保您的电脑符合Windows11的最低系统要求。接着,打开「Windows更...
- 微信好友误删了怎么加回来(微信好友误删了怎么加回来免费)
-
看到他的评论的话,你可以去你发过的内容里去看看。<br/><br/>好友验证的消息、语音)或者朋友圈内容:<br/>如果你这个朋友喜欢和你在朋友圈聊天的话,你他的手机号也有的话方法添加里输入就可...
-
- access安装包(access安装包怎么安装)
-
要下载并安装MicrosoftAccess,可以按照以下步骤进行操作:1.打开您的电脑的浏览器(如谷歌浏览器、火狐浏览器等)。2.在浏览器的搜索栏中输入"下载MicrosoftAccess"。3.从搜索结果中选择适...
-
2025-12-29 11:51 off999
- 云骑士装机大师官方网站(云骑士装机大师软件下载)
-
就是感觉正规吧,还有就是小白那种的比较多,专业店一忽悠就掏钱做系统了。懂装机的哪有花钱去装系统的不靠谱,因为会造成个人信息的泄露。云骑士装机大师是网络装机系统,在网络上能够实现一键装机,非常的简洁方便...
- 万能钥匙下载免费(安心上网万能钥匙下载免费)
-
行1.使用手机功能表中自带的浏览器上网,直接搜索需要的软件进行下载安装(下载安卓版本格式为apk)。2.使用电脑下载APK格式的安装包,连接数据线传输至手机,操作手机在应用程序-我的文件中找到安装包,...
- 500兆宽带用什么路由器(家用路由器什么牌子好 信号强)
-
1、飞鱼星千兆无线路由器家用2600M双频企业级高速穿墙500M光纤游戏加速VW1900/千兆双频/1900M/大型企业路由器无线500m推荐理由:可以提供企业级别的性能,空旷环境覆盖更广大,...
- xp系统怎么卸载软件(xp怎么卸载程序)
-
1、选中此电脑,点击鼠标右键。2、选择属性点击一下。3、在打开的界面选择控制面板。4、点击程序选项下方的卸载。5、选择要卸载的程序软件,点击鼠标右键。6、点击弹出的选项卸载/更改。7、也可以使用电脑管...
- 笔记本电脑系统修复软件(笔记本电脑程序修复)
-
1、超级兔子2013系统修复软件超级兔子是一款完整的系统维护工具。拥有电脑系统评测、垃圾清理和注册表清理、可疑文件和插件检测、网页防护等功能,同时自带一些实用的系统工具,可清理你大多数的文件、注册表里...
欢迎 你 发表评论:
- 一周热门
-
-
抖音上好看的小姐姐,Python给你都下载了
-
全网最简单易懂!495页Python漫画教程,高清PDF版免费下载
-
Python 3.14 的 UUIDv6/v7/v8 上新,别再用 uuid4 () 啦!
-
飞牛NAS部署TVGate Docker项目,实现内网一键转发、代理、jx
-
python入门到脱坑 输入与输出—str()函数
-
宝塔面板如何添加免费waf防火墙?(宝塔面板开启https)
-
Python三目运算基础与进阶_python三目运算符判断三个变量
-
(新版)Python 分布式爬虫与 JS 逆向进阶实战吾爱分享
-
失业程序员复习python笔记——条件与循环
-
系统u盘安装(win11系统u盘安装)
-
- 最近发表
- 标签列表
-
- python计时 (73)
- python安装路径 (56)
- python类型转换 (93)
- python进度条 (67)
- python吧 (67)
- python的for循环 (65)
- python格式化字符串 (61)
- python静态方法 (57)
- python列表切片 (59)
- python面向对象编程 (60)
- python 代码加密 (65)
- python串口编程 (77)
- python封装 (57)
- python写入txt (66)
- python读取文件夹下所有文件 (59)
- python操作mysql数据库 (66)
- python获取列表的长度 (64)
- python接口 (63)
- python调用函数 (57)
- python多态 (60)
- python匿名函数 (59)
- python打印九九乘法表 (65)
- python赋值 (62)
- python异常 (69)
- python元祖 (57)
