Python 条件表达式(常称「三元运算符」)
C/Java 等语言里的 ? : 在 Python 中没有相同符号,但可以用条件表达式在一行里完成「二选一」求值:
when_true if condition else when_false先求值 condition;若为真,则整个表达式的结果是 when_true 的值,否则是 when_false 的值。
官方名称是 conditional expression(条件表达式),见 语言参考:条件表达式。口语里常叫「Python 的三元运算符」。更完整的分支写法见 if / else / elif。
与多行 if / else 对比
多行:
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.")一行条件表达式:
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_true 与 when_false 里只有被选中的一侧会求值,另一侧不会执行。这对有副作用(如函数调用)的情况很重要。
下面用元组下标写法时则两侧都会先求值(见下一节)。
元组下标写法(不推荐)
有人用序列下标模拟「二选一」,例如:
x = int(input("请输入一个整数:\n"))
int_type = ("even", "odd")[x % 2]这里 x % 2 为 0 或 1,分别取元组第 0、1 个元素。注意:这是用整数下标选分支,不是把任意布尔条件直接当 0/1 用时都那么直观。
更常见的「布尔当下标」形式是 (a, b)[condition]:在 Python 里 bool 是 int 的子类,False == 0、True == 1,因此:
condition为假 → 下标0→ 取acondition为真 → 下标1→ 取b
即元组里通常是 (条件为假时的值, 条件为真时的值),顺序与条件表达式的 假分支在前、真分支在后 不同,易写反,可读性也较差。
为何更推荐 if ... else 表达式?
对 a if cond else b:先算 cond,再只计算被选中的 a 或 b。
对 (f(), g())[cond]:f() 和 g() 都会先执行,再按下标选一个结果,无法短路。
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")输出:
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 或先算中间变量:
# 可读性往往不如多行 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,不要为了少行数牺牲清晰度。