编程语言中的表达式本来只是用来产生值的,布尔表达式也不例外。布尔表达式的常规 用法是计算产生 True 或 False,并用在分支和循环控制结构当中。但 Python 中的布尔表达式 还可以用作控制结构,这是由 Python 在底层计算布尔表达式时所采用的计算策略决定的。为了理解布尔表达式如何用作控制结构,需要了解 Python 是如何实现布尔运算的,详情见第 2章。

    考虑用一个交互式循环来实现“yes or no”功能:程序询问用户一个问题,用户输入回 答。只要用户输入的字符串以“y”或者”Y”开头,就算该用户回答是 yes,程序再进行合适的 处理;否则就跳过处理过程。这个功能很容易用 while 循环语句实现:

    显然这里 while 语句中的条件表达式等同于自然语言中的“用户输入以 y 打头或者用户 输入以 Y 打头”。然而,自然语言一般不会这么罗嗦,更简洁的表达是“用户输入以 y 或 Y 打头”。可惜这种简明的表达在编程语言中常常是错误的,初学编程者受自然语言的影响,很 容易写出下面这样的布尔表达式:

    我们来看表达式 answer[0] == “y” or “Y”的计算。布尔运算符 or 所连接的两个表达式分别 是 answer[0] == “y”和”Y”,左边的表达式是真正的布尔表达式,计算结果为 True 或 False;而 右边的表达式是一个字符串,它的值就是固定的非空串”Y”。根据第 2 章中介绍的 Python 对 运算符 or 的计算规则:若 answer[0] == “y”计算到 True,则整个布尔表达式的值就是 True, 不去考虑右边的表达式;若 answer[0] == “y”计算到 False,则整个布尔表达式返回值”Y”,这 个非空串被 Python 视为 True。总之,不管用户输入的是什么,表达式 answer[0] == “y” or “Y” 永远为真,亦即 while 循环是无穷循环。

    Python 的这个特性对初学者来说是个潜在的陷阱,很容易犯错误。当然,Python 之所以 如此设计,也有它的理由,那就是布尔表达式可以用作控制结构,在某些情况下可以写出更 简明的代码。例如考虑这种需求:程序要求用户输入一个字符串,如果用户没有输入数据就 直接按了回车键,则程序采用缺省值”Python”。实现这种需求的代码如下:

    利用字符串可被 Python 解释为布尔值的特性,上面代码中 if 语句的条件可以简化成:

    根据 or 的计算规则,此处第二行语句中的 ans or “Python”等同于一个 if-else 结构,即:若 ans 非空,就直接返回它的值;若 ans 为空串,则返回”Python”。这就是我们所说的“布尔表达式 用作流程控制结构”。

    顺便说一下,如果考虑到 ans 其实就是函数 raw_input 的返回值,这个例子最终可以精简 成一行代码:

    与上面第一个版本(5 行代码)相比,显然代码量大大减少了。看上去似乎不错,但其实程 序的可读性也大大降低了,因为最后这个一行语句的版本对初学者来说是很难理解的。从良 好编程风格的角度说,宁可多写几条语句,也要保证程序的可读性和以理解性。