前言
介绍一下Python中的:= 海象运算符(walrus operator),正式名称是“赋值表达式”。它可以在表达式内部完成赋值,并返回被赋的值。
它的核心价值是:当一个值在“条件判断”里算出来,后面还要用到时,不必算两遍,也不必把代码拆成两行。
正文
基本语法
x := 10 # 错误!赋值表达式本身必须加括号(单独使用时) (x := 10) # 正确,x 被赋值为 10
规则::= 所在的赋值表达式,如果出现在语句上下文(如 if、while、for 的目标以外的位置),通常需要加括号。
用途
while中使用
基本模式
while (line := input("> ")) != "quit":
print("你输入了:", line)执行顺序
- 执行 input("> "),得到字符串;
- 把结果赋给 line;
- 判断 line != "quit";
- 若成立,进入循环体,此时 line 可直接使用。
避免了这种重复:
line = input("> ")
while line != "quit":
print("你输入了:", line)
line = input("> ") # 重复调用配合迭代器
it = iter([1, 2, 3])
while (x := next(it, None)) is not None:
print(x)一次完成:取值 + 赋值 + 判断
前提是元素中不含 None,否则用哨兵对象:
_sentinel = object()
while (x := next(it, _sentinel)) is not _sentinel:
print(x)读取文件直到空行
with open("data.txt") as f:
while (line := f.readline()):
print(line, end="")这里利用了 "空字符串为假" 的特性。
避免重复计算
while (n := expensive_computation()) > 0:
process(n)如果没有 :=,要么重复调用,要么拆成多行。
if中使用
if中使用也是比较常见。
正则匹配
import re
if (m := re.search(r"\d+", text)):
print(m.group())不用先写一行 m = re.search(...),再判断 if m:。
避免重复计算
if (length := len(data)) > 10:
print("数据太长:", length)len(data) 只算一次,length 后面还能用。
多重判断中复用结果
if (x := compute()) > 0 and x < 100:
print("合法值:", x)for中使用
for item in (items := ["a", "b", "c"]):
print(item)
print("原列表:", items)这里 items 是在 in 后面的表达式中赋值的。
# 避免重复计算 len() result = [s for s in data if (n := len(s)) > 5] # 条件里复用正则匹配结果 matches = [m.group(1) for line in lines if (m := pattern.match(line))]
注意顺序::= 赋的值,只能在当前 for / if 子句及其右侧使用。
for x in range(10):
if (y := x * x) > 50:
print(x, y)作用域规则
赋值变量
:= 赋值的变量,作用于当前函数或模块作用域,不是语句块作用域。
if (x := 10) > 5:
print(x)
print(x) # 10,仍然可访问
# y 是当前函数或模块作用域的变量,出了 if 块照样能访问。这和 for x in ... 的行为一致。
推导式中
在推导式中,:= 赋的值只在当前推导式内有效:
result = [y for x in range(3) if (y := x * 2)] print(y) # NameError #推导式结束后,y是访问不到,类似函数中局部变量,出了函数就被释放了
Python 为了防止推导式“泄漏变量”而做的特殊处理。
result = [y for x in range(3) if (y := x * 2)]
等价于下面代码,返回y不为0的所有结果
result = []
for x in range(3):
y = x * 2
if y: # 0 被过滤掉
result.append(y)小结
| 场景 | 原因 |
| while 循环需要“先算后判” | 避免重复调用 |
| if 判断后要用结果 | 避免重复计算 |
| 正则匹配 | 非常自然 |
| 推导式中避免重复计算 | 性能 + 简洁 |
:= 的意义:让“计算 → 判断 → 复用结果”这件事,可以在一个表达式里完成。
参考文章
- AI
- Python文档
