打开APP
userphoto
未登录

开通VIP,畅享免费电子书等14项超值服

开通VIP
什么是 Python 中的 Lambda?

如果你刚开始使用 Python,那么理解什么是 lambda 可能会有些混乱。

lambda 也称为匿名函数,这是因为 lambda 没有名称。要在 Python 中定义 lambda,你可以使用关键字 lambda 后跟一个或多个参数、一个冒号 (:) 和一个表达式。

我们将从一个简单的 lambda 函数示例开始,以熟悉其语法,然后我们将了解 Python lambda 函数如何适用于不同的场景。

如何在 Python 中使用 Lambda

让我们从 lambda 函数的语法开始。

lambda 函数以lambda关键字开头,后跟逗号分隔的参数列表。下一个元素是一个冒号(:),后跟一个表达式

lambda <argument(s)> : <expression>

如你所见,可以在一行中定义一个 lambda 函数。

让我们看一个非常简单的 lambda,它将数字 x(参数)乘以 2:

lambda x : 2*x

运行返回了一个函数对象。有趣的是,当我定义一个 lambda 时,我不需要 return 语句作为表达式的一部分。

如果我在表达式中包含 return 语句会怎样?

我们收到语法错误。所以,不需要在 lambda 中包含 return 。

如何在 Python 中调用 Lambda 函数

我们已经了解了如何定义 lambda,但我们如何调用它呢?

首先,我们将在不将函数对象分配给变量的情况下执行此操作。为此,我们只需要使用括号。

(lambda x : 2*x)(2)

我们将用括号将 lambda 表达式括起来,然后用括号括起我们要传递给 lambda 的参数。

这是我们运行时的输出:

我们还有另一种选择。我们可以将lambda函数返回的函数对象赋值给一个变量,然后使用变量名调用函数。

multiply = lambda x : 2*xmultiply(2)

这是我们运行时的输出:

将多个参数传递给 Lambda 函数

在前面的部分中,我们了解了如何定义和执行 lambda 函数。

我们还看到 lambda 可以有一个或多个参数,让我们看一个有两个参数的例子。

创建一个将参数 x 和 y 相乘的 lambda:

(lambda x, y : x*y)(2,3)

这是我们运行时的输出:

lambda 是一个IIFE(立即调用的函数表达式)。它基本上是一种表示 lambda 函数在定义后立即执行的方式。

Lambda 函数和常规函数之间的区别

在继续研究如何在 Python 程序中使用 lambda 之前,了解常规 Python 函数和 lambda 之间的关系很重要。

让我们以相乘的例子为例:

lambda x, y :  x*y

我们也可以使用def关键字将其编写为常规函数:

def multiply(x, y): return x*y

与 lambda 形式相比,你会立即注意到三个不同之处:

  1. 使用 def 关键字时,我们必须为我们的函数指定一个名称。

  2. 这两个参数括号括起来。

  3. 我们使用return语句返回函数的结果。

将我们的 lambda 函数分配给一个变量是可选的

multiply_lambda = lambda x, y :  x*y

让我们比较一下这两个函数的对象:

def multiply(x, y): return x*y multiply_lambda = lambda x, y : x*yprint(multiply)print(multiply_lambda)

从上面的图我们可以看到一个区别:使用 def 关键字定义的函数由名称“multiply”标识,而 lambda 函数由通用 <lambda> 标签标识。

让我们看看type() 函数在应用于这两个函数时返回的内容:

所以,这两个函数的类型是一样的。

可以在 Python Lambda 中使用 If Else 吗?

lambda x: x if x > 2 else 2*x

如果 x 大于 2,则此 lambda 应返回 x,否则应返回 x 乘以 2。
首先,让我们确认它的语法是否正确

测试一下我们的功能:

同时你可以看到,如果我们让 lambda 表达式变得越来越复杂,我们的代码会变得更难阅读。

如何用 Lambda 和 Map 替换 For 循环

在本节中,我们将看到 lambda 在应用于像Python 列表这样的可迭代对象时如何变得非常强大。

让我们从一个标准的 Python for 循环开始,循环遍历字符串列表的所有元素并创建一个新列表,其中所有元素都是大写的。

names = ['Jack', 'Elio', 'Helen']names_result = []for name in names: names_result.append(name.upper())

这是输出:

现在我们将编写相同的代码,但使用 lambda。为此,我们还将使用一个名为map的 Python 内置函数,其语法如下:

map(function, iterable, ...)

map 函数将另一个函数作为第一个参数,然后是一个可迭代列表。在这个具体的例子中,我们只有一个可迭代对象,即名字列表。

将另一个函数作为参数的函数称为高阶函数。

这听起来可能很复杂,这个例子将帮助你理解它是如何工作的。

那么,map函数有什么作用呢?

map 函数返回一个可迭代对象,它是作为第一个参数传递给可迭代对象的每个元素的函数的结果。

在我们的场景中,我们将作为第一个参数传递的函数将是一个 lambda 函数,它将其参数转换为大写格式作为可迭代的,我们将传递我们的list

map(lambda x: x.upper(), names)

上面执行会返回一个map对象。我们怎样才能取回列表呢?

我们可以将map对象转换为列表

list(map(lambda x: x.upper(), names))

很明显,与我们使用 for 循环的代码相比,使用 map 和 lambda 可以使这段代码更加简洁。

将 Lambda 函数与字典结合使用

我想尝试使用 lambda 函数从字典列表中提取特定字段。

这是很多场景都可以应用的东西,下面是一个列表里面包含字典。

people = [{'firstname':'John', 'lastname':'Ross'}, {'firstname':'Mark', 'lastname':'Green'}]

我又一次可以将 map 内置函数与 lambda 函数一起使用。

lambda 函数将一个字典作为参数并返回 firstname 键的值。

lambda x : x['firstname']

完整的表达式是:

firstnames = list(map(lambda x : x['firstname'], people))

运行输出:

将 Lambda 传递给过滤器内置函数

另一个可以与 lambda 一起使用的 Python 内置函数是filter 函数。

下面你可以看到它的语法需要一个函数和一个可迭代对象:

filter(function, iterable)

这里的想法是创建一个表达式,给定一个列表返回一个新列表,其元素匹配 lambda 函数定义的特定条件。

例如,给定一个数字列表,我想返回一个只包含负数的列表。

这是我们将使用的 lambda 函数:

lambda x : x < 0

让我们尝试执行此 lambda 并将几个数字传递给它,以便清楚 lambda 返回的内容。

(lambda x : x < 0)(-1)  # True(lambda x : x < 0)(3)  # False

我们的 lambda 返回一个布尔值:

  • 如果论证是否定的,则为真。

  • 如果参数为正则为假。

现在,让我们将此 lambda 应用于过滤器函数

numbers = [1, 3, -1, -4, -5, -35, 67]negative_numbers = list(filter(lambda x : x < 0, numbers))print(negative_numbers)

我们得到了预期的结果,一个包含所有负数的列表。

Reduce 和 Lambda 如何与列表一起使用

另一个常见的 Python 内置函数是属于functools 模块的reduce 函数

reduce(function, iterable[, initializer])

reduce 函数有什么作用?,reduce函数会对参数迭代器中的元素进行积累。

ruduce函数的定义如下:

functools.reduce(function, iterable[, initializer])

为了在实践中理解它,我们将应用一个简单的 lambda 来计算两个数字的总和到数字列表:

from functools import reducereduce(lambda x,y: x+y, [3, 7, 10, 12, 5])

运行输出:

让我们看看我们是否也可以使用 reduce 函数来连接列表中的字符串:

from functools import reducereduce(lambda x,y: x + ' ' + y, ['This', 'is', 'a', 'tutorial', 'about', 'Python', 'lambdas'])

运行输出:

应用于类的 Lambda 函数

考虑到 lambda 可以用来代替常规的 Python 函数,我们可以将 lambda 用作类方法吗?

我将定义一个名为 Gorilla 的类,它包含一个构造函数和打印消息的运行方法:

class Gorilla:    def __init__(self, name, age, weight):        self.name = name        self.age = age        self.weight = weight    def run(self):        print('{} starts running!'.format(self.name))

然后我创建了这个类的一个名为 Spartacus 的实例并在其上执行 run 方法:

Spartacus = Gorilla('Spartacus', 35, 150)Spartacus.run()

输出是:

现在,让我们用 lambda 函数替换 run 方法:

class Gorilla:    def __init__(self, name, age, weight):        self.name = name        self.age = age        self.weight = weight    run = lambda self: print('{} starts running!'.format(self.name))

在 Gorilla 类的实例上再次执行 run 方法,会看到输出消息完全相同。

将 Lambda 与排序函数一起使用

sorted 内置函数从可迭代对象返回一个排序列表。

让我们看一个简单的例子,我们将对包含一些行星名称的列表进行排序:

planets = ['saturn', 'earth', 'mars', 'jupiter'] # 排序函数按字母顺序对列表进行排序sorted(planets)

运行输出:

现在,假设我们要根据不同的标准对列表进行排序,例如每个单词的长度。

为此,我们可以使用额外的参数,它允许在进行任何比较之前提供一个应用于每个元素的函数。

sorted(planets, key=len) # ['mars', 'earth', 'saturn', 'jupiter']

在这种情况下,我们使用了 len() 内置函数,这就是行星从最短到最长排序的原因。

那么,lambda 在哪里适合所有这些?

Lambda 是函数,因此它们可以与 key 参数一起使用。

例如,假设我想根据每个行星的第三个字母对我的列表进行排序。

sorted(planets, key=lambda p: p[2]) #['jupiter', 'earth', 'mars', 'saturn']

如果我想根据特定属性的值对字典列表进行排序怎么办?

people = [{'firstname':'John', 'lastname':'Ross'},           {'firstname':'Mark', 'lastname':'Green'}]sorted(people, key=lambda x: x['lastname'])

在此示例中,我们根据姓氏键的值对字典列表进行了排序。

运行输出:

Python Lambda 和错误处理

在我们查看 lambda 和常规函数之间区别的部分中,我们看到了以下内容:

>>> multiply<function multiply at 0x101451d40>>>> multiply_lambda<function <lambda> at 0x1014227a0>

其中 multiply 是一个常规函数,multiply_lambda 是一个 lambda 函数。

如你所见,常规函数的函数对象由名称标识,而 lambda 函数对象由通用 <lambda> 名称标识。

这也使得 lambda 函数的错误处理变得更加棘手,因为 Python 回溯不包括发生错误的函数的名称。

让我们创建一个常规函数并向其传递会导致 Python 解释器引发异常的参数:

def calculate_sum(x, y):    return x+yprint(calculate_sum(5, 'Not_a_number'))

当我在 Python shell 中运行此代码时,出现以下错误:

>>> def calculate_sum(x, y):... return x+y... >>> print(calculate_sum(5, 'Not_a_number'))Traceback (most recent call last): File '<stdin>', line 1, in <module> File '<stdin>', line 2, in calculate_sumTypeError: unsupported operand type(s) for +: 'int' and 'str'

从回溯中我们可以清楚地看到错误发生在 calculate_sum 函数的第 2 行。

现在,让我们用 lambda 替换这个函数:

calculate_sum = lambda x, y: x+yprint(calculate_sum(5, 'Not_a_number'))

输出是:

>>> calculate_sum = lambda x,y: x+y>>> print(calculate_sum(5, 'Not_a_number'))Traceback (most recent call last): File '<stdin>', line 1, in <module> File '<stdin>', line 1, in <lambda>TypeError: unsupported operand type(s) for +: 'int' and 'str'

异常类型和错误消息是一样的,但是这次回溯告诉我们函数 <lambda> 的第 1 行发生了错误。想象一下,如果要你必须在 10,000 行代码中找到正确的行是不是大海捞针。这就是为啥尽可能使用常规函数而不是 lambda 函数的另一个原因。

将可变参数列表传递给 Python Lambda

在本节中,我们将了解如何向 Python lambda 提供可变参数列表。

要将可变数量的参数传递给 lambda,我们可以像使用常规函数一样使用*args :

lambda *args: max(args))(5, 3, 4, 10, 24)

当我们运行它时,我们得到传递给 lambda 的参数之间的最大值:

>>> (lambda *args: max(args))(5, 3, 4, 10, 24)24

我们不一定要使用关键字 args。重要的是 args 之前的 * 在 Python 中代表可变数量的参数。

让我们通过用数字替换 args 来确认是否是这种情况:

>>> (lambda *numbers: max(numbers))(5, 3, 4, 10, 24)24

Lambda 函数的更多示例

如果你想在 Python 程序中使用 lambda,这些示例应该会给你更多的想法。

给定一个 Linux 命令列表,只返回以字母“c”开头的命令:

>>> commands = ['ls', 'cat', 'find', 'echo', 'top', 'curl']>>> list(filter(lambda cmd: cmd.startswith('c'), commands))['cat', 'curl']

从带空格的逗号分隔字符串返回一个列表,其中包含不带空格的字符串中的每个单词:

>>> weekdays = 'monday   , tuesday, wednesday,thursday,   friday,  saturday  ,sunday'>>> list(map(lambda word: word.strip(), weekdays.split(',')))['monday', 'tuesday', 'wednesday', 'thursday', 'friday', 'saturday', 'sunday']

使用 Python range 函数生成数字列表并返回大于四的数字:

>>> list(filter(lambda x: x > 4, range(15)))[5, 6, 7, 8, 9, 10, 11, 12, 13, 14]

结论

在本篇文章中,我们了解了什么是 Python lambda,以及如何定义和执行它。

我们浏览了带有一个或多个参数的示例,我们还看到了 lambda 如何返回一个函数对象(不需要 return 语句)。

现在你知道 lambda 也称为匿名函数,因为当你定义它时,你不会将它绑定到一个名称。

此外,分析 Python 中常规函数和 lambda 函数之间的区别有助于我们更好地理解 lambda 的工作原理。

当你的代码中只需要一次时,使用 lambda 函数是很常见的。如果你需要在代码库中多次调用的函数,使用常规函数是避免代码重复的更好方法。

永远记住编写干净的代码是多么重要,任何人都可以快速理解的代码,以防将来出现需要快速修复的错误。

现在你可以在 lambda 表达式和常规函数之间做出选择,做出正确的选择!

本站仅提供存储服务,所有内容均由用户发布,如发现有害或侵权内容,请点击举报
打开APP,阅读全文并永久保存 查看更多类似文章
猜你喜欢
类似文章
【热】打开小程序,算一算2024你的财运
10分钟快速入门Python函数式编程
Python学习笔记(十二):lambda表达式与函数式编程
如何用十分钟学会函数式 Python?
写 Python 代码不可不知的函数式编程技术
Python 十大装 B 语法
Python中的函数式编程教程,学会用一行代码搞定所有内容
更多类似文章 >>
生活服务
热点新闻
分享 收藏 导长图 关注 下载文章
绑定账号成功
后续可登录账号畅享VIP特权!
如果VIP功能使用有故障,
可点击这里联系客服!

联系客服