Python中a < b < c被解释为a < b and b < c,b仅求值一次;它非左结合,也不等价于(a < b) < c,此设计保障行为正确与安全性。

a < b < c 不是简单地从左到右计算,也不是等价于 (a < b) < c。
它会被 Python 解释器整体重写为 a < b and b < c,且中间操作数 b 只求值一次 —— 这是关键设计,直接影响行为和安全性。
链式比较不是左结合表达式
很多人误以为 a 等价于 <code>(a 。但实际不是:<code>a 返回布尔值(<code>True 或 False),而 True 会触发隐式整数转换(<code>True == 1, False == 0),导致意外结果。
例如:
立即学习“Python免费学习笔记(深入)”;
>>> a, b, c = 5, 10, 3 >>> a < b < c # 实际是 5 < 10 and 10 < 3 → False False >>> (a < b) < c # 先算 5 < 10 → True → 1 < 3 → True True
两者语义完全不同,后者毫无业务意义,还容易掩盖逻辑错误。
含函数调用时,链式比较能避免重复执行
当比较中涉及有副作用或高开销的函数时,链式写法天然安全;而手动拆成 and 很可能重复调用。
0 :<code>get_value()只执行 1 次0 :<code>get_value()执行 2 次,可能返回不同值,也可能浪费资源
尤其在数据库查询、API 调用、IO 操作等场景下,这个差异直接决定程序是否正确。
图片提示词生成器?不止如此。 马甲系统 —— 把脑海中的画面,翻译成AI能理解的专业表达。 用得越多,它越懂你:首次需要多问几句确认方向,用久了几乎一说就懂。 用得越多,它越快:缓存机制让后续对话越来越省。 RAG进化:成功案例持续入库,越跑越聪明。 输入「新手指南」查看完整功能介绍
自定义类的 __lt__ 和 __le__ 必须一致
链式比较依赖每个独立比较的返回值,如果类实现了 __lt__ 但没实现 __le__,或者两个方法逻辑冲突(比如 a 为 <code>True,但 a 返回 <code>False),就会出现反直觉结果。
例如:
立即学习“Python免费学习笔记(深入)”;
class BadNumber:
def __init__(self, x): self.x = x
def __lt__(self, other): return self.x < other.x
def __le__(self, other): return self.x < other.x # 错!漏了等于情况
<p>a, b = BadNumber(5), BadNumber(5)
print(a < b) # False
print(a <= b) # False ← 违反数学常识
print(a < b <= b) # False and False → False,但直觉上希望是 False(因为 a < b 不成立),可问题在于 <= 行为本身已错
所以链式比较对自定义类的协议一致性要求更高,不能只实现部分比较方法。
混合类型比较不会因链式而“绕过”类型检查
Python 在链式比较中仍会对每一对操作数做类型兼容性检查。比如 "5" 会直接报错:
TypeError: '<' not supported between instances of 'str' and 'int'
错误发生在第一个不兼容比较处("5" ),不会等到第二个比较才暴露。这点和手动写 <code>and 完全一致,但初学者常误以为链式会“跳过”或“智能转换”。
链式比较真正难的点不在语法,而在它悄悄改变了求值次数和依赖关系——一旦中间值有副作用、状态变化或性能代价,就很容易掉进坑里。写的时候顺手,查 bug 时却要倒回去确认每个子表达式是否被复用。

















