Python 3.8 的赋值表达式与海象运算符

本文介绍了Python 3.8中的新特性——赋值表达式(海象运算符)。通过示例展示了如何使用这个运算符来简化代码,尤其是在条件判断和循环中的应用,提醒开发者在追求代码压缩的同时要保持可读性。

1. 简介

Python 3.8 引入了 PEP 572 中描述的新特性——赋值表达式,该语法由 Emily Morehouse 实现。没错,就是下面这个妹子。


2. 语法与语义

赋值表达式,这是 PEP 572 标题中使用的官方正式名称,英文是 Assignment Expressions。也可以称作具名表达式,英文是 Named Expressions。它涉及到的新操作符 := 被亲切地称作海象运算符,英文是 the walrus operator,因为冒号 : 像是海象的一对小眼睛,等号 = 像是海象的一对长牙。

赋值表达式的语法是 NAME := expr,顾名思义,它完成了两个操作:

  • 计算表达式 expr 的结果
  • 把结果赋值给名为 NAME 的变量

注意:

  • 在大多数 Python 表达式可以出现的上下文中,都可以使用赋值表达式。一些例外情况在 PEP 572 中有所提及,刚开始使用不用在意,大体准则是不要在没有必要或者影响代码可读性的时候使用赋值表达式。
  • 变量名 NAME 是有效的 Python 标识符,表达式 expr 可以是除了不带括号的元组以外的任意合法 Python 表达式。
  • 赋值表达式的值与它包含的表达式 expr 的值是一样的,同时还会把该值赋给 NAME

3. 作用与案例

先来看一个最简单的:

>>> walrus = False
>>> print(walrus)
False
>>> print(walrus := True)
True
>>> walrus
True

可见 print(walrus := True) 一句话,做了两句话的工作:

  • walrus = True
  • print(walrus)

你想直接写成 print(walrus = True)?在 Python 中是不行的:

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

知道赋值表达式和海象运算符的好了吧,它可以压缩代码量,也就是压行。这下力扣上的 Python 题解又会多出很多一行解,这在以前可是做不到的。

具体来说,海象运算符经常用于给稍后需要使用的条件表达式起名字,比如 if 语句或者是 while 语句后面跟着的表达式。这么说有点不直观,再来看一个例子。

我们想要在字符串 'apple' 中从头匹配 'app',然后输出匹配到的内容,一般可以这么做:

>>> import re
>>> m = re.match(r'app', 'apple')
>>> if m is not None:
...     print('匹配到了:', m)
...
匹配到了: <re.Match object; span=(0, 3), match='app'>

借助海象运算符,可以实现压行,改成下面这么写也没问题:

>>> import re
>>> if (m := re.match(r'app', 'apple')) is not None:
...     print('匹配到了:', m)
...
匹配到了: <re.Match object; span=(0, 3), match='app'>

注意 (m := re.match(r'app', 'apple')) 两边的括号不能省略,否则等价于下面的代码:

if m := (re.match(r'app', 'apple') is not None):
    ...

这样得到的 m 值为 True,就不是我们想要的 Match 对象了。

再看一个用于 while 循环的例子:

>>> while (s := input('说点什么:')) != 'q':
...     print('你输入了:' + s)
...
说点什么:hello
你输入了:hello
说点什么:world
你输入了:world
说点什么:q

上面的代码不停地读取用户输入,在不为 'q' 的情况下打印输入。如果不用海象运算符,需要这么写才行:

>>> while 1:
...     s = input('说点什么:')
...     if s == 'q':
...         break
...     print('你输入了:' + s)
...
说点什么:hello
你输入了:hello
说点什么:world
你输入了:world
说点什么:q

两相比较之下,海象运算符压缩的可不仅仅是一行两行这么简单。(仔细数了数,没说错,压缩了三行。)

除此之外,海象运算符还可以复用计算开销大的值:

# Reuse a value that's expensive to compute
[y := f(x), y**2, y**3]

或者是在列表推导式的过滤子句中共享一个子表达式,这其实也算是用在 if 后面的一个例子:

# Share a subexpression between a comprehension filter clause and its output
filtered_data = [y for x in data if (y := f(x)) is not None]

更多关于海象运算符的用法和注意事项可以查看 PEP 572,切记不要为了纯粹炫技而影响代码可读性。海象虽好,可不要瞎用哦!


4. 相关资料


评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值