海象运算符就是 Python 里的 :=,正式名称叫“赋值表达式”。它从 Python 3.8 开始支持。

之所以叫“海象”,是因为:

1
:=

看起来有点像海象的眼睛和獠牙,噗。

1. 它是干什么的?

普通赋值使用 =

1
2
name = input("请输入名字:")
print(name)

海象运算符 := 可以在表达式内部赋值,同时返回这个值

1
print(name := input("请输入名字:"))

这行代码相当于:

1
2
name = input("请输入名字:")
print(name)

执行后,变量 name 依然存在。


2. 最典型的用法:减少重复计算

假设要判断字符串长度:

1
2
3
4
text = input("请输入内容:")

if len(text) > 10:
print(f"内容太长,共有 {len(text)} 个字符")

这里 len(text) 写了两次,可以用海象运算符:

1
2
3
4
text = input("请输入内容:")

if (length := len(text)) > 10:
print(f"内容太长,共有 {length} 个字符")

执行过程是:

  1. 计算 len(text)
  2. 把结果赋值给 length
  3. 使用 length 的值继续进行 > 10 判断

注意这里通常要加括号:

1
2
if (length := len(text)) > 10:
...

3. 在 while 循环中使用

这是海象运算符非常经典的场景。

普通写法:

1
2
3
4
5
line = input("请输入内容:")

while line != "quit":
print("你输入了:", line)
line = input("请输入内容:")

使用海象运算符:

1
2
while (line := input("请输入内容:")) != "quit":
print("你输入了:", line)

每次循环时都会:

1
line = input(...)

然后判断:

1
line != "quit"

这样不用在循环前和循环末尾分别写一次 input()


4. 在正则匹配中使用

不用海象运算符:

1
2
3
4
5
6
import re

match = re.search(r"\d+", "订单编号是 12345")

if match:
print(match.group())

使用海象运算符:

1
2
3
4
import re

if match := re.search(r"\d+", "订单编号是 12345"):
print(match.group())

re.search() 成功时会返回匹配对象,失败时返回 None

因此这里同时完成了:

1
match = re.search(...)

和:

1
if match:

5. 在列表推导式中使用

假设有一些数字,只保留平方大于 20 的结果。

普通写法会重复计算平方:

1
2
3
numbers = [1, 2, 3, 4, 5, 6]

result = [x * x for x in numbers if x * x > 20]

使用海象运算符:

1
2
3
4
5
6
numbers = [1, 2, 3, 4, 5, 6]

result = [square for x in numbers if (square := x * x) > 20]

print(result)
# [25, 36]

这里每个数字的平方只计算一次。

不过列表推导式中使用海象运算符容易降低可读性,不要为了炫技硬塞进去。


6. =:= 的区别

普通赋值 =

它是一条赋值语句:

1
x = 10

不能直接放进某些表达式中:

1
2
if x = 10:  # SyntaxError
pass

海象运算符 :=

它是一个表达式:

1
2
if (x := 10):
print(x)

因为 x := 10 的结果是 10,而 10 被视为真,所以会进入 if


7. 为什么经常需要括号?

海象运算符的优先级比较低,括号可以明确表达你的意图。

推荐写法:

1
2
if (count := len(items)) > 5:
print(count)

不推荐写得过于模糊:

1
2
if count := len(items) > 5:
print(count)

这段代码中的 count 得到的不是长度,而是比较结果:

1
count = len(items) > 5

也就是 TrueFalse

例如:

1
2
3
4
items = [1, 2, 3, 4, 5, 6]

if count := len(items) > 5:
print(count)

输出:

1
True

而不是:

1
6

所以要写成:

1
2
if (count := len(items)) > 5:
print(count)

输出:

1
6

这是非常容易踩的小坑。


8. 不能完全替代普通赋值

不能这样给属性赋值:

1
obj.value := 10

也不能这样给列表元素赋值:

1
items[0] := 10

海象运算符左侧通常必须是一个简单变量名:

1
value := 10

而普通赋值支持:

1
2
obj.value = 10
items[0] = 10

9. 什么时候适合使用?

适合:

1
2
if (result := expensive_function()) is not None:
use(result)
1
2
while chunk := file.read(1024):
process(chunk)
1
2
if match := pattern.search(text):
print(match.group())

不适合把大量逻辑挤成一行:

1
2
if (data := get_data()) and (items := parse(data)) and (valid := check(items)):
...

虽然能运行,但读起来像解谜游戏。

更清晰的写法可能是:

1
2
3
4
5
6
7
8
9
10
data = get_data()
if not data:
return

items = parse(data)
if not items:
return

if check(items):
...

一句话记忆

1
变量 := 表达式

表示:

计算表达式,把结果保存到变量中,并立即把这个结果用于当前位置。

比如:

1
2
if (n := len("hello")) > 3:
print(n)

相当于:

1
2
3
4
n = len("hello")

if n > 3:
print(n)

海象运算符的核心价值不是“少写一行”,而是当一个计算结果既要用于判断、又要在后面继续使用时,避免重复计算。