海象运算符

Python
565
0
0
2022-10-12
标签   Python基础

6.7 海象运算符

说明:本文是正在编写的《Python完全自学教程》的草稿节选,此处先睹为快。关于本书的详细内容,参阅 www.itdiffer.com

Python3.8 引入了一种叫做海象运算符(Walrus Operator)的新语法——本书演示用的是 Python 3.9 ,它其实是一种赋值语句,用于解决 Python 语言中长期存在的、可能导致代码重复的问题。

正常的赋值语句是 a = b ,海象赋值语句是

a := b

符号 := 看起来像一对眼球和两只獠牙,类似于海象,故命名之。

先用一个简单示例,了解海象运算符的应用方法。

>>> print(b=3.14)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: 'b' is an invalid keyword argument for print()

这样做报错,不能在 print() 函数里面进行赋值操作,必须先赋值,然后执行 print() 函数,即:

>>> b = 3.14
>>> print(b)
3.14

但是,这样做,就多了一行赋值语句,本来这也没有什么大不了的,但是 Python 3.8 开始对这个不大不小的事情提供了另外一种解决方案:海象运算符——在本不能实现赋值的地方能够进行赋值。

>>> print(w := 3.14)
3.14

将此代码与前述代码比较,观察其差异。再次声明,这种海象运算符必须用于 Python 3.8 及更高版本中。

也许上面的示例太简单了,没有感觉到海象运算符的魅力——必须声明,不用它也能够完成程序,它的作用主要在于减少程序的行数。

#coding:utf-8
'''
filename: whilewalrus.py
'''
value = input('please enter something:')        # (1)
while value != "":
    print('Nice! Again.')
    value = input('please enter something:')    # (2)

这段程序的意图是让用户输入一些内容,如果输入的不是“空”(直接敲回车,即输入了“空”),就允许继续不断输入。注释(1)通过赋值语句得到了用户输入的字符串(用变量 value 引用),然后是 while 循环语句,如果 value != "" 成立,则在注释(2)中继续让用户输入,并用变量 value 引用所捕获的输入字符串,然后通过 while 循环语句判断,……,如此循环。其中,注释(1)和注释(2)是两行完全一样的赋值语句,只是位置不同。如果没有海象运算符,上述程序是说得过去的——至少能实现意图。然而,现在我们可以用海象运算法,将其改造得更优雅。

while value := input('please enter something:') != "":    # (3) 
    print('Nice! Agian.')

两行实现!在 while 循环中不能使用普通的赋值语句,但是能够像注释(3)那样使用有海象运算符的赋值语句,从而减少了代码行数。

类似的应用场景还很多,再比如:

>>> lst = [-1, -2, -3, 1, 2, 3]
>>> [abs(x) for x in lst if abs(x) <= 2]    # (4)
[1, 2, 1, 2]
>>> [y for x in lst if (y := abs(x)) <= 2]  # (5)
[1, 2, 1, 2]

注释(4)的列表解析中,要计算两次 abs(x) ,在注释(5)中,使用海象运算符,只要计算一次即可。

>>> a = [1, 2, 3, 4]
>>> n = len(a)
>>> if n > 3:
...     print(f"list is too long ({n} elements, expected <= 3)")
...
list is too long (4 elements, expected <= 3)

# 使用海象运算符
>>> if (m := len(a)) > 3:
...     print(f"list is too long ({m} elements, expected <= 3)")
...
list is too long (4 elements, expected <= 3)

上述示例显示了在 if 条件语句中使用海象运算符。

6.3.1节的程序 sumhundred.py 也可以用海象运算符改造。

sum = 0
result = [sum := sum + i for i in range(1, 101)]
print(f"the sum of 1 to 100 is: {result[-1]}")

程序中的 result 是一个列表,它的最后一项 result[-1] 即为 1~100 的整数和,其它项是依次叠加的结果。

在许多情况下,海象运算符的赋值表达式可以消除代码中的冗余。通常,在多行中多次重复同一个表达式或赋值时,可以考虑使用海象运算符来提高可读性。当然,不用它也不会影响程序运行。

自学建议 Python 的软件版本号分 3 段:A.B.C ,其含义为:
  • A 表示大版本号。通常标志着 Python 整体有较大变化,甚至出现不向后兼容的改变。到目前就经历了多个版本,以大版本号为例:1994年发布 Python 1.0 ,2000年发布 Python 2.0 ,2008年发布 Python 3.0 。
  • B 表示在大版本的范围内的功能更新,比如 Python 3.8 相对此前的 Python 3.x 版本,就增加了本节的海象运算符。
  • C 表示更小的修改,如修复某些 Bug 等。以本书演示用的版本 Python 3.9.4 为例,解决了 Python 3.9.3 中 ABI 不兼容的问题。

就学习者而言,通常建议在大版本的范畴内,尽可能以最新版本作为学习对象。如果在使用本书学习的时候,读者使用了其他 Python 3.8+ 的版本,一般而言对学习不会有影响。但是,如果使用的是 Python 3.8 以下的版本,除了如本节这样对版本做特别声明的,其他章节内容也不受影响。 如果读者还想了解每个版本的改进细节,可以参考官方网站发布的信息。