Skip to content

Python 条件表达式(常称「三元运算符」)

C/Java 等语言里的 ? : 在 Python 中没有相同符号,但可以用条件表达式在一行里完成「二选一」求值:

text
when_true if condition else when_false

先求值 condition;若为,则整个表达式的结果是 when_true 的值,否则是 when_false 的值。

官方名称是 conditional expression(条件表达式),见 语言参考:条件表达式。口语里常叫「Python 的三元运算符」。更完整的分支写法见 if / else / elif

与多行 if / else 对比

多行:

python
x = int(input("请输入一个整数:\n"))

if x % 2 == 0:
    int_type = "even"
else:
    int_type = "odd"

print(f"You entered {x} which is an {int_type} integer.")

一行条件表达式:

python
x = int(input("请输入一个整数:\n"))

int_type = "even" if x % 2 == 0 else "odd"

print(f"You entered {x} which is an {int_type} integer.")

逻辑相同;在分支都很短、只选一个值时,条件表达式更紧凑。

短路求值

when_truewhen_false 里只有被选中的一侧会求值,另一侧不会执行。这对有副作用(如函数调用)的情况很重要。

下面用元组下标写法时则两侧都会先求值(见下一节)。

元组下标写法(不推荐)

有人用序列下标模拟「二选一」,例如:

python
x = int(input("请输入一个整数:\n"))

int_type = ("even", "odd")[x % 2]

这里 x % 201,分别取元组第 0、1 个元素。注意:这是用整数下标选分支,不是把任意布尔条件直接当 0/1 用时都那么直观。

更常见的「布尔当下标」形式是 (a, b)[condition]:在 Python 里 boolint 的子类False == 0True == 1,因此:

  • condition 为假 → 下标 0 → 取 a
  • condition 为真 → 下标 1 → 取 b

即元组里通常是 (条件为假时的值, 条件为真时的值),顺序与条件表达式的 假分支在前、真分支在后 不同,易写反,可读性也较差。

为何更推荐 if ... else 表达式?

a if cond else b先算 cond,再只计算被选中的 ab

(f(), g())[cond]f()g() 都会先执行,再按下标选一个结果,无法短路。

python
def foo(s):
    print(f"foo called with parameter {s}")
    return s


flag = True

if flag:
    result = foo("if")
else:
    result = foo("else")

result = foo("ternary-if") if flag else foo("ternary-else")

result = (foo("tuple-true"), foo("tuple-false"))[flag]

print("Done")

输出:

text
foo called with parameter if
foo called with parameter ternary-if
foo called with parameter tuple-true
foo called with parameter tuple-false
Done

可见 if ... else 表达式只调用了 foo('ternary-if')元组写法两个 foo 都执行了。若分支里有昂贵计算或副作用,应使用条件表达式,而不是元组下标。

嵌套与可读性

可以嵌套,但很容易难读,一般应用多行 if / elif 或先算中间变量:

python
# 可读性往往不如多行 if/elif
label = "A" if x > 0 else ("B" if x == 0 else "C")

小结

  • Python 用 when_true if condition else when_false 实现「三元」选择,且短路
  • 元组 + 下标 容易混淆顺序,且不短路,多数场景不推荐
  • 分支复杂时优先 if / elif / else,不要为了少行数牺牲清晰度。

参考