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. 相关资料

  • PEP 572
  • Assignment Expressions: The Walrus Operator
  • Try out walrus operator in Python 3.8

Python 3.8 的赋值表达式与海象运算符相关推荐

  1. stata行业变量怎么赋值_PEP572:赋值表达式(海象符)

    阅读 PEP 是理解 Python 特性的绝好方式.Python 3.8 引入了赋值表达式,它是什么?怎么用?有什么限制?话不多说,直接看 PEP. 一.简介 本提案建议在 Python 中增加 := ...

  2. python范围运算符_Python的海象运算符

    作者:Brett Slatkin 翻译:老齐 Python3.8引入了一种叫做海象运算符(walrus)的新语法(译者注: 对于walrus的翻译,目前尚未出现对于Python的专门术语翻译,所以,此 ...

  3. python海象运算符_【译】Python3.8新语法:海象运算符

    作者:Brett Slatkin 翻译:老齐 与本文内容有关的图书:<跟老齐学Python:轻松入门>.<Python大学实用教程> Python3.8引入了一种叫做海象运算符 ...

  4. Python 海象运算符,威力无穷!

    文 | 闲欢 来源:Python 技术「ID: pythonall」 大家好,我是闲欢,你们的老相识呀! 海象可谓是最大的哺乳动物了,有人称它是北半球的"土著"居民.它圆头,短而阔 ...

  5. Python神奇的海象运算符:=使用教程

    := (海象运算符)是 Python 3.8 引入的一种新的赋值语法,也称为指定分配(又称为等号赋值或链接赋值). 海象运算符的英文原名叫 Assignment Expresions ,即 赋值表达式 ...

  6. python海象运算符

    简介 Python 海象运算符是在 PEP 572 中提出,并在 Python3.8 版本并入发布. 海象运算符的英文原名叫 Assignment Expresions ,即 赋值表达式.海象表达式由 ...

  7. 三种常见的Python赋值表达式的写法!

    Python的赋值表达式英文原名为Assignment Expressions,因为它太像海象了所以又被称为海象运算符.今天小千就来给大家介绍一下三种常见的赋值表达式的写法,大家来了解一下以防将来遇到 ...

  8. python赋值表达式_6. 表达式

    6.表达式¶ 本章将解释 Python 中组成表达式的各种元素的的含义. 语法注释: 在本章和后续章节中,会使用扩展 BNF 标注来描述语法而不是词法分析. 当(某种替代的)语法规则具有如下形式 na ...

  9. 海象赋值表达式减少重复变量

    海象赋值表达式减少重复变量 1.概述 在写代码过程中,定义局部变量操作频率非常高.如果在一个函数中定义了太多的变量会让程序不易维护且阅读起来困难. 当我们在函数里面要定义变量时,而且这个变量要在函数里 ...

最新文章

  1. 【FFmpeg】截至ffmpeg4.2不推荐(Deprecate)继续使用的接口,以及代替它的接口汇总
  2. centos6 rpm安装mysql_Centos6下rpm安装MySQL5.6
  3. c语言程序设计血型与遗传报告,血型遗传关系C语言编程
  4. SAP用户权限相关操作
  5. 程序员面试100题之十四:强大的和谐
  6. 前端学习(2647):vue3.0的认识
  7. What is an Operating System?
  8. 计算机专业本科毕业转行会计,大学里就业最难的5个专业,毕业后难找工作,很多同学都转行了!...
  9. mysql 动态加载数据库数据库连接,如何根据每个客户端动态连接mysql数据库?
  10. 【Pre-Training】超细节的 BERT/Transformer 知识点
  11. 计算机设计大赛无人车挑战赛
  12. python中判断对象是否可迭代
  13. ramoops具体失败原因来解释驱动寄存器
  14. javascript获取TreeView控件选中节点的Text和Value
  15. [转贴]彻底解决 CrystalReports 登录失败问题。
  16. FREETEXTBOX
  17. 使用ThinkPHP扩展,实现Redis的CURD操作。
  18. pajek中文乱码:ASCII字符处理
  19. 水星如何设置虚拟机服务器,水星mercury路由器电脑怎么设置?
  20. 电视与电脑连接html线,电视机与电脑连接的方法

热门文章

  1. BLE蓝牙特定机型权限问题(例如小米)
  2. 什么牌子的蓝牙耳机耐用?2023年最值得入手的蓝牙耳机推荐
  3. Android vold介绍
  4. TexturePacker 文件解释工具,方便分析动画
  5. 教育减负和关注语文的目的就是为既得利益者构建阶层壁垒
  6. Java知识(static修饰符和fina修饰符l)
  7. [Minecraft] 从零开始搭建4位CPU(1)
  8. 修改pipenv虚拟环境安装位置
  9. isnumeric java_你知道ApacheCommon包中isNumeric方法是坑吗-百度经验
  10. 超越CLIP!谷歌大脑多模态学习新作CLIPPO:仅从像素理解图像和语言