Python 海象操作符

一、 介绍

Python 赋值表达式(assignment expression)是Python 3.8新引入的语法,它会用到海象操作符(walrus operator)。

这种写法可以解决某些持续已久的代码重复问题。a = b是一条普通的赋值语句,读作a equals b,而a := b则是赋值表达式,读作a walrus b。

这个符号为什么叫walrus呢?因为把:=顺时针旋转90º之后,冒号就是海象的一双眼睛,等号就是它的一对獠牙。

二、语法

海象操作符的语法格式是:

(variable_name := expression or value)

即一个变量名后跟一个表达式或者一个值,这个和赋值运算符 = 类似,可以看作是一种新的赋值运算符。

三、 用法

1、 if-else 结构

比如制作一份果汁,需要先取水果,判断有足够的水果时,才能制作。

一般写法:

count = fresh_fruit.get('apple', 0)
if count >= 4:    
    make_cider(count)
else:    
    out_of_stock()

海象操作符:

if (count:fresh_fruit.get('apple', 0)) >= 4:    
    make_cider(count)
else:    
    out_of_stock()

2、switch/case结构

如果想按照一定的顺序自动给客人制作饮品,这样就不用点餐了。

下面这段逻辑先判断能不能做香蕉冰沙,如果不能,就做苹果汁,还不行,就做柠檬汁

count = fresh_fruit.get('banana', 0)
if count >= 2:
    pieces = slice_bananas(count)
    to_enjoy = make_smoothies(pieces)
else:
    count = fresh_fruit.get('apple', 0)
    if count >= 4:
        to_enjoy = make_cider(count)
    else:
        count = fresh_fruit.get('lemon', 0)
        if count:
            to_enjoy = make_lemonade(count)
        else:
            to_enjoy = 'Nothing'

这种难看的写法,其实在Python里特别常见。现在有了海象操作符,就能够轻松地模拟出很接近switch/case的方案。

if (count := fresh_fruit.get('banana', 0)) >= 2:
    pieces = slice_bananas(count)
    to_enjoy = make_smoothies(pieces)
elif (count := fresh_fruit.get('apple', 0)) >= 4:
    to_enjoy = make_cider(count)
elif count := fresh_fruit.get('lemon', 0):
    to_enjoy = make_lemonade(count)
else:
    to_enjoy = 'Nothing'

3、 do/while结构

(1)n 次循环的一般写法:

n = 6
while n:
    print('hello, walrus operator!')
    n -= 1

海象操作符:

n = 7
while (n := n - 1) + 1: # 需要加1是因为执行输出前n就减1了
    print('hello, walrus operator!')

(2) 实现一个密码输入检验的一般写法:

while True:
    test = input("请输入密码:")
    if test == "123":
        break

更优雅的实现方式:海象操作符。

while (test := input("请输入密码:")) != "123":
    continue

(3)读取一个文件的每一行并输出:

fp = open("test.txt", "r")
while True:
    line = fp.readline()
    if not line:
        break
    print(line.strip())
fp.close()

更简洁的实现:

fp = open("test.txt", "r")
while line := fp.readline():
    print(line.strip())

4、列表推导式

计算元素平方根,并保留平方根大于 5 的值:

nums = [16, 36, 49, 64]

def f(x):
    print('运行了函数f(x)1次。')
    return x ** 0.5

print([f(i) for i in nums if f(i) > 5])

以上执行后的输出为:

运行了函数f(x)1次。
运行了函数f(x)1次。
运行了函数f(x)1次。
运行了函数f(x)1次。
运行了函数f(x)1次。
运行了函数f(x)1次。
运行了函数f(x)1次。
[6.0, 7.0, 8.0]

一共就 4 个数字,但是函数被执行了 7 次。这是因为有三个数字满足列表推导式的条件,需要再额外计算 3次。当程序数据巨大的时候,这将浪费大量性能。

让我们来看看使用 := 的实现结果如何:

nums = [16, 36, 49, 64]
def f(x):
    print('运行了函数f(x)1次。')
    return x ** 0.5
print([n for i in nums if (n := f(i)) > 5])

执行后的输出:

运行了函数f(x)1次。
运行了函数f(x)1次。
运行了函数f(x)1次。
运行了函数f(x)1次。
[6.0, 7.0, 8.0]

函数只执行了 4 次,函数执行结果被 n 储存,不需要额外计算。性能优于不使用 := 的。

当然,海象操作符同样适合用于字典推导式和集合推导式。

四、参考

1、https://zhuanlan.zhihu.com/p/67192546

posted @ 2023-02-09 16:20  xyztank  阅读(74)  评论(0编辑  收藏  举报