表达式与一行写法
条件表达式
Python 的一行条件表达式顺序是“真值在前,条件居中,假值在后”:
python
label = "adult" if age >= 18 else "minor"它是表达式,可以嵌入函数参数或容器;但不要堆叠多层:
python
# 能运行,但阅读成本高
level = "high" if score >= 90 else "mid" if score >= 60 else "low"分支只会执行一个,适合简单取值,不适合塞入具有副作用的复杂流程。
推导式
python
squares = [x * x for x in values if x >= 0]
mapping = {user.id: user.name for user in users}
unique = {normalize(x) for x in values}阅读顺序对应普通循环:
python
result = []
for x in values:
if x >= 0:
result.append(x * x)多个 for 从左到右嵌套:
python
pairs = [(x, y) for x in xs for y in ys if x != y]不要用推导式只为副作用,例如 [print(x) for x in values] 会额外创建一组 None。此时使用普通 for。
and 与 or 返回操作数
and、or 返回最后求值的操作数,不保证返回 bool:
python
name = supplied_name or "anonymous"
token = user and user.token
print(0 or 5) # 5
print("ok" and 7) # 7这类默认值写法会把 0、""、[] 等合法假值也当作缺失。只有 None 表示缺失时,应显式判断:
python
timeout = default_timeout if supplied_timeout is None else supplied_timeout比较链
python
0 <= index < len(items)等价于 0 <= index and index < len(items),但中间表达式只求值一次。a < b > c 也合法,含义是 a < b and b > c,不是比较三个值递增。
海象运算符
:= 在表达式中赋值,适合避免重复计算:
python
if (count := len(items)) > 100:
print(f"too many items: {count}")python
while chunk := stream.read(8192):
process(chunk)括号常用于消除优先级歧义。不要用海象运算符把一行写成隐藏多次状态变化的脚本。
幂运算与负号
** 比左侧一元负号结合更紧,并且从右向左结合:
python
-2**2 # -(2**2) == -4
(-2)**2 # 4
2**3**2 # 2**(3**2) == 512同时,2**-1 合法,因为右侧一元运算按语法规则参与指数表达式,结果为 0.5。
取整除与余数
// 是向负无穷取整,不是简单截断小数:
python
-3 // 2 # -2
-3 % 2 # 1Python 保持 a == (a // b) * b + (a % b)。处理跨语言算法时尤其要检查负数除法语义。
is 与 in
==比较值,is比较对象身份。- 与
None比较使用is None。 - 不要因小整数或字符串驻留在某次运行中让
a is b恰好为真,就用is比较数值或文本。 x in dict检查 Key,不检查 Value。x in generator会消费元素,可能使后续迭代从中间继续或直接耗尽。
一行不等于更 Pythonic
一行表达式适合无副作用的映射、过滤和简单取值。出现以下情况应拆开:
- 嵌套条件表达式。
- 推导式包含多个副作用。
- 需要记录中间变量解释业务含义。
- 异常处理、资源释放或多个状态更新。
- 为追求一行而重复昂贵计算。