作者选择了COVID-19 救济基金来接受捐赠,作为Write for DOnations计划的一部分。
介绍
2019 年 10 月发布的Python 3.8通过:=
语法为 Python 添加了赋值表达式。赋值表达式语法有时也被称为“海象运算符”,因为它:=
有点像长着獠牙的海象。
赋值表达式允许变量赋值发生在较大的表达式中。虽然赋值表达式对于编写正确的 Python 代码从来不是绝对必要的,但它们可以帮助使现有的 Python 代码更加简洁。例如,使用:=
语法的赋值表达式允许在if
statements内部分配变量,这通常可以通过消除if
语句前后行中的变量赋值来生成更短、更紧凑的 Python 代码部分。
在本教程中,您将在几个示例中使用赋值表达式来生成简洁的代码段。
先决条件
要充分利用本教程,您需要:
-
Python 3.8 或更高版本。赋值表达式是从 Python 3.8 开始添加的新功能。您可以查看如何在 Ubuntu 18.04 服务器上安装 Python 3 和设置编程环境教程,以帮助安装和升级 Python。
-
Python 交互式控制台。如果您想尝试本教程中的示例代码,可以使用如何使用Python 交互式控制台教程。
-
熟悉Python 3 中的
while
循环、if
语句、列表推导式和函数很有用,但不是必需的。您可以查看我们的How To Code in Python 3系列教程以获取背景知识。
在if
语句中使用赋值表达式
让我们从一个如何在if
语句中使用赋值表达式的示例开始。
考虑以下检查列表长度并打印语句的代码:
some_list = [1, 2, 3]
if (list_length := len(some_list)) > 2:
print("List length of", list_length, "is too long")
如果您运行前面的代码,您将收到以下输出:
OutputList length of 3 is too long
您初始化一个名为的列表some_list
,该列表包含三个元素。然后,该if
语句使用赋值表达式((list_length := len(some_list))
将命名的变量绑定list_length
到 的长度some_list
。该if
语句计算为True
因为list_length
大于2
。您使用list_length
变量打印字符串,该变量最初与赋值表达式绑定,表明三元素列表太长。
注意:赋值表达式是Python 3.8 中引入的一个新特性。要运行本教程中的示例,您需要使用 Python 3.8 或更高版本。
如果我们没有使用赋值表达式,我们的代码可能会稍微长一些。例如:
some_list = [1, 2, 3]
list_length = len(some_list)
if list_length > 2:
print("List length of", list_length, "is too long")
此代码示例是等同于第一实施例,但是这个代码需要一个额外的独立行的值绑定list_length
到len(some_list)
。
另一个等效的代码示例可能只计算len(some_list)
两次:一次在if
语句中,一次在print
语句中。这将避免产生将变量绑定到 的值所需的额外行len(some_list)
:
some_list = [1, 2, 3]
if len(some_list) > 2:
print("List length of", len(some_list), "is too long")
赋值表达式有助于避免额外的行或双重计算。
注意:赋值表达式是一个有用的工具,但不是绝对必要的。当代码显着提高段落的可读性时,请使用您的判断并在代码中添加赋值表达式。
在下一节中,我们将探索在while
循环内使用赋值表达式。
在while
循环中使用赋值表达式
赋值表达式通常在while
循环中工作得很好,因为它们允许我们将更多上下文折叠到循环条件中。
考虑以下input
在while
循环条件中嵌入用户函数的示例:
while (directive := input("Enter text: ")) != "stop":
print("Received directive", directive)
如果您运行此代码,Python 将不断提示您从键盘输入文本,直到您键入单词stop
。一个示例会话可能如下所示:
>>> while (directive := input("Enter text: ")) != "stop":
... print("Received directive", directive)
...
Enter text: hello
Received directive hello
Enter text: example
Received directive example
Enter text: stop
>>>
赋值表达式(directive := input("Enter text: "))
将 的值绑定directive
到通过input
函数从用户处检索到的值。您将返回值绑定到变量directive
,然后在while
循环体中打印出来。while
只要您键入,循环就会退出stop
。
如果您没有使用赋值表达式,您可能已经编写了一个等效的input
循环,例如:
directive = input("Enter text: ")
while directive != "stop":
print("Received directive", directive)
directive = input("Enter text: ")
此代码在功能上与带有赋值表达式的代码相同,但总共需要四行(而不是两行)。它还会input("Enter text: ")
在两个地方复制调用。当然,编写等效while
循环的方法有很多,但前面介绍的赋值表达式变体很紧凑,并且很好地捕捉了程序的意图。
到目前为止,您已经在if
语句和while
循环中使用了赋值表达式。在下一节中,您将在列表推导式中使用赋值表达式。
在列表推导式中使用赋值表达式
我们也可以在列表推导式中使用赋值表达式。列表推导式允许您通过迭代序列并可能将满足某些条件的元素添加到列表中来简洁地构建列表。与列表推导式一样,我们可以使用赋值表达式来提高可读性并使我们的代码更加简洁。
考虑以下示例,该示例使用列表推导式和赋值表达式来构建乘以整数的列表:
def slow_calculation(x):
print("Multiplying", x, "*", x)
return x * x
[result for i in range(3) if (result := slow_calculation(i)) > 0]
如果您运行前面的代码,您将收到以下信息:
OutputMultiplying 0 * 0
Multiplying 1 * 1
Multiplying 2 * 2
[1, 4]
你定义一个函数命名slow_calculation
是乘以给定数量x
与本身。列表解析反复的遍历0
,1
以及2
由归国range(3)
。赋值表达式将值绑定result
到slow_calculation
with的返回值i
。result
只要大于 0 就将加入到新建的列表中。在本例中,0
、1
、 和2
都与自己相乘,但只有结果1
( 1 * 1
) 和4
( 2 * 2
) 满足大于0
条件并成为最终结果的一部分列表[1, 4]
。
该slow_calculation
函数的绝对值不一定很慢,但旨在说明有关效率的一个重要观点。考虑上一个没有赋值表达式的示例的替代实现:
def slow_calculation(x):
print("Multiplying", x, "*", x)
return x * x
[slow_calculation(i) for i in range(3) if slow_calculation(i) > 0]
运行此程序,您将收到以下输出:
OutputMultiplying 0 * 0
Multiplying 1 * 1
Multiplying 1 * 1
Multiplying 2 * 2
Multiplying 2 * 2
[1, 4]
在前面代码的这个变体中,您没有使用赋值表达式。相反,您slow_calculation
最多调用两次:一次以确保slow_calculation(i)
大于0
,第二次可能将计算结果添加到最终列表中。0
只与自身相乘一次,因为0 * 0
不大于0
。然而,其他结果会被双重计算,因为它们满足大于 0 的条件,然后重新计算它们的结果以成为最终列表的一部分[1, 4]
。
您现在已经将赋值表达式与列表推导式结合起来,以创建既高效又简洁的代码块。
结论
在本教程中,您使用赋值表达式来制作 Python 代码的紧凑部分,为if
语句、while
循环和列表推导式中的变量赋值。
有关其他赋值表达式的更多信息,您可以查看PEP 572——最初提议向 Python 添加赋值表达式的文档。
您可能还想在我们的主题页面上查看我们的其他 Python 内容。