在不讨论 lambda 表达式的情况下, 我很难深入地讲授 Python 类. 我经常遇到有关它们的问题. 学生们往往会在 StackOverflow 或者他们同事的代码中(实际上, 这个也可能来自StackOverflow)碰到他们.
我对 lambda 有很多的疑问, 我很犹豫是否要推荐学生接受 Python lambda 表达式. 多年来我一直都很厌恶 lambda 表达式, 自从几年前我开始频繁教授 Python 后, 我对它的厌恶与日俱增.
我将会说明我对 lambda 表达式的看法, 以及为何我倾向于建议学生们避免使用它.
更多Python视频、源码、资料加群683380553免费获取
Python 中的 lambda 表达式: 它们是什么?
lambda 表达式是 Python 中创建匿名函数的一个特殊语法. 我称 lambda 语法本身为 lambda 表达式, 而它返回的函数我称之为 lambda 函数.
Python 的 lambda 表达式允许在一行代码中创建一个函数并传递(通常传递到另外一个函数).
lambda 表达式允许我们使用此代码:
并将其转换为以下代码:
lambda 表达式仅仅是创建函数的一个特殊方法. 它们只包含一条语句, 并自动返回这条语句的结果.
lambda 表达式本身的局限性实际上是其吸引力的一部分. 当经验丰富的 Python 程序员看到一个lambda 表达式时, 他们知道他们正在使用一个仅在一个地方有效的函数, 并且只做一件事情.
如果你曾经在 JavaScript 中使用过匿名函数, 那么Python 中的 lambda 表达式与之相同, 除了具有更多限制以及与传统函数完全不同的语法.
通常使用的地方
你通常会在调用接受函数作为参数的函数(或类)时, 使用 lambda 表达式.
Python 内置的 sorted 函数接受一个函数作为它的 key 参数. 这个 key 函数用于在决定条目排序顺序时计算比较键的值.
所以 sorted 可以作为一个经常使用 lambda 表达式范例:
上述代码返回了对给定颜色以不区分大小写方式排序的结果.
sorted 函数并不是 lambda 表达式的唯一用法, 但却是最普遍的一个.
lambda 的利弊
围绕 lambda 表达式和 def 定义的函数之间的一系列对比, 我发表一下看法. 这两类工具都可以提供函数, 但它们都有各自的限制, 使用了不同的语法.
lambda 表达式与 def 的主要不同点:
- 可以立刻传递(无需变量)
- 在内部只能包含一行代码
- 自动返回结果
- 既没有文档字符串, 也没有名称
- 使用了不同且不常见的语法
事实上, lambda 表达式能够被传递是它们最大的优势. 自动返回结果很简洁, 但在我看来并不是很大的优势. "单行代码"的限制总体上不好不坏. 而 lambda 函数没有文档字符串和名称令人遗憾, 而它们的一些不常见的语法可能会对新的Pythonista造成困扰.
总的来说, 我觉得 lambda 表达式的缺点略微超过了它的优点, 但我对它们最大的怨念是它们往往被滥用或者过度使用.
lambda 被滥用和过度使用
当我在陌生代码中看到 lambda 表达式时, 我立刻会新生疑虑. 当我在自然环境下遇到 lambda 表达式时, 我经常发现去掉它们之后能提高代码的稳定性.
有时候 lambda 表达式会被滥用, 意味着它们的使用方式通常不理想. 另外有时候 lambda 表达式仅仅被过度使用, 意味着它们可以被接受, 但我个人更愿意看到以其他不同方式编写的代码.
让我们来看一下 lambda 表达式被滥用和过度使用的几种方式.
滥用: 命名 lambda 表达式
官方 Python 风格指南 PEP8 建议永远不要编写这样的代码:
上述语句创建了一个匿名函数并赋值到一个变量. 上面的代码忽视了用 lambda 的原因: lambda 函数可以被直接传递而无需先赋值给一个变量.
如果你想创建一个一行代码的函数并存储到变量中, 你应该使用def:
PEP8 推荐这种方式, 因为命名函数是一个常见并容易理解的东西. 同时给函数一个合适的名称也是很有好处的, 可以让调试简单一些. 而与 def 定义的函数不同, lambda 函数从来都没有一个名称(名称都是<lambda>):
如果你想创建一个函数并存储到变量中, 请使用 def 来定义. 这正是它的用途. 无论你的函数是一行代码还是在另外一个函数中定义, 都可以, def 正适合这些应用场景.
滥用: 调用不必要的函数
我经常看到用 lambda 表达式封装一个已经很适合当前问题的函数.
例如这段代码:
写这段代码的人很可能了解过, 知道 lambda 表达式是用来创建一个可传递函数的. 但他们却忽略了一个更大一些的理念: Python 中所有的函数(不止 lambda 函数)都是可传递的.
既然 abs(返回一个数字的绝对值) 是一个函数并且所有函数都是可传递的, 实际上我们可以将上述代码编写为:
这个例子可能会让人感到有些假, 但以这种方式来使用 lambda 表达式并不十分罕见. 这是我看到的另外一个例子:
因为我们接受与我们传给 min 完全相同的参数, 所以完全没有必要调用额外的函数. 我们可以直接将 min 函数传递给 key:
如果你已经有了另一个符合你要求的函数, 则不需要一个 lambda 函数.
过度使用: 简单, 但不常用的函数
lambda 表达式通常用于创建一个在元组中返回一系列值的函数.
这里的 key 所传的函数让我们可以根据长度以及大小写标准化的名称来对颜色进行排序.
下面的代码与上面的功能相同, 但我认为更有可读性:
代码看上去有点啰嗦, 但我觉得 key 函数的名称可以让排序的依据更加清晰. 我们不是只依据长度排序, 也不是只依据颜色排序: 我们同时使用了两者.
如果一个函数很重要, 那么它应当有一个名称. 你可以争论说, lambda 表达式中使用的大多数函数都不重要, 不值得给一个名称, 但命名函数通常没什么缺点, 而且我发现它通常会使我的代码整体上可读性更好.
给函数命名通常会让代码更有可读性, 同样的, 使用元组拆包来命名变量而不是使用随机索引查找的方式通常会让代码更有可读性.
过度使用: 多行代码有帮助的时候
有时候 lambda 表达式"只有一行"这方面的特性会导致我们用复杂的方式来编写代码. 例如下面的例子:
在这里我们对索引查找做了硬编码以按照颜色来对点进行排序. 如果我们使用一个命名函数, 我们可以用元组拆包来让代码更有可读性:
比起使用硬编码索引查找,元组拆包可以提升可读性. 使用 lambda 表达式通常意味着牺牲掉一些 Python 语言的特性, 尤其是需要多行代码的时候(比如额外的赋值语句).
过度使用: lambda 与 map 和 filter
Python 的 map 和 filter 函数经常与 lambda 表达式搭配在一起使用. 当在 StackOverflow 上提问"什么是 lambda 表达式"的问题时, 经常会看到以下例子中的代码:
Python 的 map 和 filter 函数用来循环并创建一个新的可迭代对象, 循环期间对每个元素做一些细微修改或者根据匹配的条件过滤到只剩一些元素. 我们完全可以只使用列表推导和生成器表达式来完成这两项任务:
滥用: 有时你甚至不需要去传递一个函数
那需要传递并执行单个操作函数的情况该怎么办?
热衷于函数式编程的新 Pythonistas 有时会写如下的代码:
上述代码对 numbers 列表中的所有数字做了加法. 但还有一个更好的方式来做这个操作:
Python 内置的 sum 函数就是专门做这个任务的.
sum 函数以及其他的一些专门的 Python 工具很容易被忽视. 但我建议你在需要时寻找更专业的工具, 因为它们通常会让代码更有可读性.
与其传递一个函数到其他函数中, **不如观察一下是否有更专业的方式来解决你的问题. **
过度使用: 使用 lambda 进行非常简单的操作
我们不说加法了, 再来说一下乘法吧:
上面的 lambda 表达式是很有必要的, 因为不允许我们传递 * 运算符, 就算它像一个函数一样. 如果有一个等价于 * 的函数, 我们就可以将它传递给 reduce 函数.
Python 的标准库实际上有一个完整的模块来解决这个问题:
Python 的运算符模块让 Python 的各种运算符像函数一样易用. 如果你正在练习函数式编程, Python 的 operator 模块就是你的好助手.
除了提供与 Python 许多运算符相对应的函数以外, operator 模块还提供了一系列常用的更高级的函数来访问条目和属性, 以及调用方法.
itemgetter 用来访问列表/序列的索引或字典/映射的键值:
attrgetter 用来访问对象的属性:
methodcaller 用来调用对象的方法:
我通常发现使用 operator 模块中的函数会使代码看上去比使用等效的 lambda 表达式更加清晰易懂.
过度使用: 当给高阶函数增加困惑时
一个接收其他函数作为参数的函数被称为高阶函数. 高阶函数通常就是我们经常向其传递 lambda 函数的那一类函数.
在练习函数式编程时高阶函数是很常用的. 然而函数式编程并不是应用 Python 思想的唯一方式: Python 是一种多范式语言, 因此我们可以混合并匹配编码规则, 让我们的代码更有可读性.
对比这个:
和这个:
第二段代码长一些, 但是没有函数式编程背景的人通常会觉得它更容易理解.
很多 Python 程序员来说, reduce/lambda 的组合可能都会有些晦涩难懂.
通常, 将一个函数传递给另一个函数会使代码更加复杂, 这不利于代码的可读性.
你应该使用 lambda 表达式吗?
基于以下原因, 我觉得 lambda 表达式的应用是有问题的:
- 对很多 Python 程序员来说, lambda 表达式是一种古怪而又陌生的语法
- lambda 函数本身缺少名称和文档, 意味着了解它们功能的唯一方式就是读代码
- lambda 表达式只能包含一条语句, 因此某些提高可读性的语言功能, 如元组拆包, 不能与它们一起使用
- lambda 函数通常可以被替换为标准库中已存在的函数或 Python 内置的函数
比起一个命名良好的函数, lambda 表达式缺乏即刻可读性. 尽管 def 语句通常更容易理解, 但 Python 还有很多可用于替换 lambda 表达式的功能, 包括特殊语法(推导), 内置函数(sum)和标准库函数(在 operator 模块中)
只有当你的情况完全满足这四个标准时, 我才会说你可以使用 lambda 表达式:
- 你所要做的操作是不重要的: 函数不值得一个名称
- 使用 lambda 表达式比你所能想到的函数名称让代码更容易理解
- 你很确定还没有一个函数能满足你的需求
- 你团队的每个人都了解 lambda 表达式, 并且都同意使用它们
如果上述四条中的任何一条都不符合你的情况, 我建议用 def 来写一个新的函数, (如果可能)接受一个在 Python 中已经存在且能满足你需求的函数.
来自 <https://blog.csdn.net/sinat_38682860/article/details/83933866>
相关推荐
使用环境:需要先安装PyCharm(请自己百度下载安装),以及然后官网上下载Python 2.7版本,以及Python 3.7版本后,安装在自己的电脑上。...目的:帮助理解lambda表达式定义函数在Python中的具体使用。
内容概要:python、lambda表达式的用法举例。 采用.txt 文本格式。无需解压,直接使用。...能学到什么:学习python中lambda表达式的语法、各种常见的用法。 阅读建议:大量用例可以直接复制拷贝到IDE中进行测试。
Python 利用lambda表达式简化编程 Python源码Python 利用lambda表达式简化编程 Python源码Python 利用lambda表达式简化编程 Python源码Python 利用lambda表达式简化编程 Python源码Python 利用lambda表达式简化编程 ...
Lambda表达式是Python编程语言中的一个重要特性,它允许程序员创建匿名函数,即没有正式名称的函数。这种功能在需要快速定义小型、一次性的函数时非常有用,尤其在函数式编程风格中。下面我们将深入探讨Lambda表达式...
### Python中 Lambda表达式全面解析 #### 一、Lambda表达式的定义与特点 Lambda表达式在Python中是一种特殊的函数形式,它允许我们快速定义一个简短的匿名函数。这种匿名函数通常用于那些只需要使用一次或者不需要...
Python中的Lambda表达式是一种简洁的创建匿名函数的方式。在编程中,函数是可重用的代码块,用于执行特定任务。而Lambda表达式允许我们在一行内定义这些函数,无需为它们指定名称,这就是“匿名”一词的由来。 ...
如果你在学校读的是计算机科学专业,那么可能学过 Lambda 表达式, 不过可能从来没有用过它。如果你不是计算机科学专业,它们看着可能 有点儿陌生(或者只是“曾经学习过的东西”)。在这一节里,虽然我们 不打算...
Python中的lambda表达式是一种简洁的创建单行、小型匿名函数的方式。这些函数没有名称,因此称为匿名,通常用于实现简单的、一次性使用的功能。在Python编程中,lambda表达式常被用作函数参数,特别是在需要一个简短...
### Python使用Lambda表达式对字典排序操作详解 在Python编程中,经常需要对字典进行排序处理。本文将深入探讨如何使用`lambda`表达式来实现字典的按键排序、按值排序以及多条件排序。 #### Lambda表达式简介 ...
在Python中,`lambda`表达式特别常见,因为它们可以帮助我们快速编写简洁的一行函数。本文将深入探讨如何将字符串转换为`lambda`表达式,以及这种技术在实际应用中的价值。 首先,我们要理解`lambda`表达式的语法。...
python lambda表达式 在Python中,lambda表达式是一种匿名函数的简洁表示方式。
lambda表达式语法如下 函数名 = lambda 参数 : 参数表达式 在使用的时候 函数名(变量) eg. 通过常规方式定义函数 if x<y: res = x+y else: res = x-y return res print(fun(1,3)) # 4 通过lambda表达式...
lambda 表达式,又称匿名函数,即,函数没有具体的名称,常用来表示内部仅包含 1 行表达式...仅仅能在 lambda 表达式中封装有限的逻辑进去。 lambda 函数拥有自己的命名空间,且不能访问自有参数列表之外或全局命名空间
综上所述,Python中的函数和lambda表达式是编程中不可或缺的基础工具,它们提供了代码的封装、复用和模块化能力,帮助程序员编写出结构清晰、易于维护的代码。掌握函数和lambda表达式的使用对于任何Python开发者来说...
Python3中sorted()函数与lambda表达式原理解析相信很多小伙伴们在一开始学习Python的一些高级用法时遇到过很多困扰。我准备日常分享一些比较浅显的原理解析帮助大家理解。博主的原文:lambda表达式sorted()函数目录...
在Python编程语言中,条件表达式和lambda表达式是两种非常实用的语法结构,它们各自在不同的场景下发挥着重要作用。接下来,我们将深入探讨这两种表达式的概念、用法以及应用场景。 首先,条件表达式(也称作三元...
Python是一种广泛使用的高级编程语言,由Guido van Rossum于1989年底发明,第一个公开发行版...6. **解释型语言**:Python是一种解释型语言,这意味着开发过程中没有编译步骤。 7. **动态类型系统**:Python不会在编写
在Python编程中,lambda表达式是一种简洁的创建匿名函数的方式,尤其在处理简短的、一次性的函数时非常实用。本资源"核心基础-利用lambda表达式简化编程-Python实例源码.zip"提供了关于如何使用lambda表达式进行编程...