带有示例的 Python Lambda 函数
什么是 Python 中的 Lambda 函数?
Python 中的 Lambda 函数 编程是一个匿名函数或没有名字的函数。这是一个小而受限制的功能,不超过一条线。就像一个普通函数一样,一个 Lambda 函数可以有多个参数和一个表达式。
在 Python 中,lambda 表达式(或 lambda 形式)用于构造匿名函数。为此,您将使用 lambda 关键字(就像你使用 def 定义正常功能)。你在 Python 中定义的每个匿名函数都会有 3 个基本部分:
- lambda 关键字。
- 参数(或绑定变量),以及
- 函数体。
一个 lambda 函数可以有任意数量的参数,但函数体只能包含 一个 表达。此外,lambda 是用一行代码编写的,也可以立即调用。您将在接下来的示例中看到这一切的实际效果。
在这个 Python 中的 Lambda 教程中,您将学习:
- 语法和示例
- 在 Python 内建函数中使用 lambdas
- filter() 中的 lambdas
- map() 中的 lambdas
- reduce() 中的 lambdas
- 为什么(以及为什么不)使用 lambda 函数?
- Lambda 与常规函数
语法和示例
编写 lambda 函数的正式语法如下:
lambda p1, p2: expression
这里,p1 和 p2 是传递给 lambda 函数的参数。您可以根据需要添加任意数量的参数。
但是,请注意,我们没有像使用常规函数那样在参数周围使用括号。最后一部分(表达式)是对您提供给函数的参数进行操作的任何有效的 Python 表达式。
示例 1
现在您已经了解了 lambda,让我们通过一个示例来尝试一下。所以,打开你的 IDLE 并输入以下内容:
adder = lambda x, y: x + y print (adder (1, 2))
这是输出:
3
代码说明
在这里,我们定义一个变量来保存 lambda 函数返回的结果。
1. 用于定义匿名函数的 lambda 关键字。
2. x 和 y 是我们传递给 lambda 函数的参数。
3. 这是函数的主体,它添加了我们传递的 2 个参数。请注意,它是单个表达式。您不能在 lambda 函数的主体中编写多个语句。
4. 我们调用函数并打印返回值。
示例 2
这是一个了解 lambda 基础知识和语法的基本示例。现在让我们尝试打印出一个 lambda 并查看结果。再次,打开您的 IDLE 并输入以下内容:
#What a lambda returns string='some kind of a useless lambda' print(lambda string : print(string))
现在保存文件并按 F5 运行程序。这是你应该得到的输出。
输出:
<function <lambda> at 0x00000185C3BF81E0>
这里发生了什么事?让我们看代码进一步理解。
代码说明
- 在这里,我们定义了一个字符串,您将把它作为参数传递给 lambda。
- 我们声明一个调用 print 语句并打印结果的 lambda。
但是为什么程序不打印我们传递的字符串呢?这是因为 lambda 本身返回一个函数对象。在这个例子中,lambda 没有被调用 通过打印功能,但只是返回 函数对象和存储它的内存位置。这就是在控制台上打印的内容。
示例 3
但是,如果您编写这样的程序:
#What a lambda returns #2 x="some kind of a useless lambda" (lambda x : print(x))(x)
然后按 F5 运行它,你会看到这样的输出。
输出:
some kind of a useless lambda
现在,正在调用 lambda,并且我们传递的字符串在控制台上打印出来。但是那个奇怪的语法是什么,为什么括号中包含 lambda 定义?现在让我们明白这一点。
代码说明
- 这是我们在上一个示例中定义的相同字符串。
- 在这一部分中,我们定义了一个 lambda,并通过将字符串作为参数传递来立即调用它。这就是所谓的 IIFE,您将在本教程的后续部分中了解有关它的更多信息。
示例 4
让我们看最后一个例子来了解 lambda 和常规函数是如何执行的。因此,打开您的 IDLE 并在一个新文件中输入以下内容:
#A REGULAR FUNCTION def guru( funct, *args ): funct( *args ) def printer_one( arg ): return print (arg) def printer_two( arg ): print(arg) #CALL A REGULAR FUNCTION guru( printer_one, 'printer 1 REGULAR CALL' ) guru( printer_two, 'printer 2 REGULAR CALL \n' ) #CALL A REGULAR FUNCTION THRU A LAMBDA guru(lambda: printer_one('printer 1 LAMBDA CALL')) guru(lambda: printer_two('printer 2 LAMBDA CALL'))
现在,保存文件并按 F5 运行程序。如果你没有犯任何错误,输出应该是这样的。
输出:
打印机 1 定期呼叫
打印机 2 常规呼叫
打印机 1 LAMBDA CALL
打印机 2 LAMBDA CALL
代码说明
- 一个名为 guru 的函数,它将另一个函数作为第一个参数,并在其后接受任何其他参数。
- printer_one 是一个简单的函数,它打印传递给它的参数并返回它。
- printer_two 与printer_one 类似,但没有return 语句。
- 在这一部分中,我们将调用 guru 函数并将打印机函数和一个字符串作为参数传递。
- 这是实现第四步(即调用 guru 函数)但使用 lambdas 的语法。
在下一节中,您将学习如何将 lambda 函数与 map(), 一起使用 减少(), 和 filter() 在 Python 中。
在 Python 内建函数中使用 lambdas
Lambda 函数提供了一种优雅而强大的方式来使用 Python 中的内置方法执行操作。这是可能的,因为可以立即调用 lambdas 并将其作为参数传递给这些函数。
Python Lambda 中的 IIFE
IIFE 代表 立即调用的函数执行。 这意味着一旦定义了 lambda 函数,就可以调用它。让我们通过一个例子来理解这一点;启动你的 IDLE 并输入以下内容:
(lambda x: x + x)(2)
这是输出和代码说明:
这种立即调用 lambda 的能力允许您在 map() 和 reduce() 等函数中使用它们。它很有用,因为您可能不想再次使用这些功能。
filter() 中的 lambdas
过滤器功能用于从元素序列中选择一些特定的元素。序列可以是任何迭代器,如列表、集合、元组等。
将选择的元素基于一些预定义的约束。它需要2个参数:
- 定义过滤约束的函数
- 序列(任何迭代器,如列表、元组等)
例如,
sequences = [10,2,8,7,5,4,3,11,0, 1] filtered_result = filter (lambda x: x > 4, sequences) print(list(filtered_result))
这是输出:
[10, 8, 7, 5, 11]
代码说明:
1. 在第一个语句中,我们定义了一个称为序列的列表,其中包含一些数字。
2. 在这里,我们声明了一个名为filtered_result的变量,它将存储filter()函数返回的过滤值。
3. 一个 lambda 函数,它在列表的每个元素上运行,如果它大于 4,则返回 true。
4。 打印过滤器函数返回的结果。
map() 中的 lambdas
map 函数用于将特定操作应用于序列中的每个元素。和filter()一样,它也需要2个参数:
- 定义要对元素执行的操作的函数
- 一个或多个序列
例如,这是一个打印给定列表中数字平方的程序:
sequences = [10,2,8,7,5,4,3,11,0, 1] filtered_result = map (lambda x: x*x, sequences) print(list(filtered_result))
输出:
[100, 4, 64, 49, 25, 16, 9, 121, 0, 1]
[KR1]
代码说明:
- 在这里,我们定义了一个名为序列的列表,其中包含一些数字。
- 我们声明了一个名为 filters_result 的变量,它将存储映射的值
- 对列表的每个元素运行并返回该数字的平方的 lambda 函数。
- 打印map函数返回的结果。
reduce() 中的 lambdas
reduce 函数,如 map(),用于对序列中的每个元素应用操作。但是,它的工作方式与地图不同。以下是 reduce() 函数计算输出所遵循的步骤:
步骤 1) 对序列的前 2 个元素执行定义的操作。
步骤 2) 保存此结果
步骤 3) 使用保存的结果和序列中的下一个元素执行操作。
第 4 步) 重复直到没有更多的元素。
它还需要两个参数:
- 定义要执行的操作的函数
- 序列(任何迭代器,如列表、元组等)
例如,这是一个返回列表中所有元素的乘积的程序:
from functools import reduce sequences = [1,2,3,4,5] product = reduce (lambda x, y: x*y, sequences) print(product)
这是输出:
120
代码说明:
- 从 functools 模块导入 reduce
- 在这里,我们定义了一个名为序列的列表,其中包含一些数字。
- 我们声明了一个名为 product 的变量,它将存储减少的值
- 在列表的每个元素上运行的 lambda 函数。它将根据之前的结果返回该数字的乘积。
- 打印reduce函数返回的结果。
为什么(以及为什么不)使用 lambda 函数?
正如您将在下一节中看到的,lambda 在解释器级别被视为与常规函数相同。在某种程度上,您可以说 lambda 为编写返回单个表达式的函数提供了紧凑的语法。
但是,您应该知道何时使用 lambdas 是个好主意以及何时避免使用它们。在本节中,您将了解 Python 开发人员在编写 lambda 时使用的一些设计原则。
lambdas 最常见的用例之一是函数式编程,因为 Python 支持一种称为函数式编程的编程范式(或风格)。
它允许您将一个函数作为参数提供给另一个函数(例如,在 map、filter 等中)。在这种情况下,使用 lambdas 提供了一种优雅的方式来创建一次性函数并将其作为参数传递。
什么时候不应该使用 Lambda?
您永远不应该在生产环境中编写复杂的 lambda 函数。维护您的代码的编码人员很难解密它。如果您发现自己在制作复杂的单行表达式,那么定义一个合适的函数将是一种更好的做法。作为最佳实践,您需要记住简单的代码总是比复杂的代码更好。
Lambda 与常规函数
如前所述,lambdas [vV4][J5] 只是没有绑定标识符的函数。简而言之,它们是没有名称的函数(因此是匿名的)。这里有一张表格来说明 lambdas 和 python 中常规函数的区别。
Lambdas
常规函数
语法:
lambda x : x + x
语法:
def (x) : return x + x
Lambda 函数的主体中只能有一个表达式。
正则函数的主体中可以有多个表达式和语句。
Lambda 没有与之关联的名称。这就是为什么它们也被称为匿名函数。
常规函数必须有名称和签名。
Lambda 不包含 return 语句,因为 body 会自动返回。
需要返回值的函数应该包含return语句。
解释不同之处?
lambda 和常规函数之间的主要区别在于 lambda 函数只计算一个表达式并产生一个函数对象。因此,我们可以将 lambda 函数的结果命名并在我们的程序中使用它,就像我们在前面的示例中所做的那样。
上述示例的常规函数如下所示:
def adder (x, y): return x + y print (adder (1, 2))
在这里,我们必须定义一个 name 对于返回的函数 我们调用时的结果 它。 lambda 函数不包含 return 语句,因为它只有一个表达式,默认情况下总是返回。您甚至不必分配 lambda,因为它可以立即调用(请参阅下一节)。正如您将在下面的示例中看到的,当我们将 lambdas 与 Python 的内置函数一起使用时,它们变得特别强大。
但是,您可能仍然想知道 lambda 与返回单个表达式的函数(如上面的那个)有何不同。在解释器级别,没有太大区别。这听起来可能令人惊讶,但您在 Python 中定义的任何 lambda 函数都会被解释器视为普通函数。
正如您在图中看到的,这两个定义在转换为字节码时由 python 解释器以相同的方式处理。现在,你不能命名一个函数 lambda 因为它是 Python 保留的,但是任何其他函数名都会产生相同的字节码[KR6]。
总结
- Lambda 也称为匿名函数,是小型的受限函数,不需要名称(即标识符)。
- Python 中的每个 lambda 函数都有 3 个基本部分:
- lambda 关键字。
- 参数(或绑定变量),以及
- 函数体。
- 编写 lambda 的语法是:lambda parameter:expression
- Lambda 可以有任意数量的参数,但它们不包含在大括号中
- 一个 lambda 在其函数体中只能有 1 个表达式,默认返回。
- 在字节码级别,解释器处理 lambda 和常规函数的方式没有太大区别。
- Lambda 通过以下语法支持 IIFE:(lambda 参数:表达式)(参数)
- Lambdas 通常与以下 python 内置函数一起使用:
- 过滤器:过滤器(lambda 参数:表达式,可迭代序列)
- 映射:映射(lambda 参数:表达式,可迭代序列)
- reduce:reduce(lambda parameter1,parameter2:表达式,iterable-sequence)
- 不要在生产环境中编写复杂的 lambda 函数,因为这对于代码维护人员来说会很困难。
[J5]我添加了一个表格,但是需要解释才能理解差异。
Python