如何在Python中使用赋值表达式

来自菜鸟教程
跳转至:导航、​搜索

作者选择了 COVID-19 Relief Fund 作为 Write for DOnations 计划的一部分来接受捐赠。

介绍

Python 3.8 于 2019 年 10 月发布,通过 := 语法向 Python 添加赋值表达式。 赋值表达式语法有时也称为“海象运算符”,因为 := 隐约类似于长着獠牙的海象。

赋值表达式允许变量赋值发生在较大的表达式中。 虽然赋值表达式对于编写正确的 Python 代码并不是绝对必要的,但它们可以帮助使现有的 Python 代码更加简洁。 例如,使用 := 语法的赋值表达式允许在 if 语句 内部分配变量,这通常可以通过消除前面或在 if 语句之后。

在本教程中,您将在几个示例中使用赋值表达式来生成简洁的代码段。

先决条件

要充分利用本教程,您需要:

if 语句中使用赋值表达式

让我们从一个如何在 if 语句中使用赋值表达式的示例开始。

考虑以下检查 list 长度并打印语句的代码:

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 循环 中运行良好,因为它们允许我们将更多上下文折叠到循环条件中。

考虑以下在 while 循环条件中嵌入用户 input 函数的示例:

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 循环体中打印出来。 只要您键入 stopwhile 循环就会退出。

如果您没有使用赋值表达式,您可能已经编写了一个等效的 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 与自身相乘。 然后列表推导遍历 range(3) 返回的 012。 赋值表达式将值 result 绑定到 slow_calculationi 的返回值。 只要 result 大于 0,就将其添加到新建列表中。 在此示例中,012 都与自身相乘,但只有结果 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 内容。