逻辑值检测

任何对象都可以进行逻辑值的检测,以便在 if 或 while 作为条件,条件是有条件执行中最基本的部分。

一个对象在默认情况下均被视为真值,除非该对象所属类定义了 __bool__() 方法且返回 False 或是定义了 __len__() 方法且返回零。

下面是 Python 中被视为假值到内置对象:

  • 内置值:None 和 False

  • 任何数值类型中的零:0,0.0,0j,Decimal(0),Fraction(0, 1)

  • 空的序列和多项集:’’,(),[],{},set(),range(0)

产生布尔值结果的运算和内置函数总是返回 0 或 False 作为假值,1 或 True 作为真值,除非另行说明。(重要例外:布尔运算 or 和 and 总是返回其中一个操作数。)

比较运算符

在条件表达式中,最基本的运算符可能是比较运算符 ,它们用于执行比较。

表达式

描述

x == y

x 等于 y

x < y

x 小于 y

x > y

x 大于 y

x >= y

x 大于或等于 y

x <= y

x 小于或等于 y

x != y

x 不等于 y

x is y

x 和 y 是同一个对象

x is not y

x 和 y 是不同的对象

x in y

x 是容器(如序列)y 的成员

x not in y

x 不是容器(如序列)y 的成员

Note

从理论上说,可使用 < 和 <= 等运算符比较任意两个对象 x 和 y 的相对大小,并获得一个真值,但这种比较仅在 x 和 y 的类型相同或相近时(如两个整数或一个整数和一个浮点数)才有意义。

将整数与字符串比毫无意义,这时通常会抛出 TypeError。

与赋值一样,Python 也支持链式比较,可同时使用多个比较运算符,如 0 < age < 100

有些比较运算符需要特别注意,下面详细介绍。

相等运算符

要确定两个对象是否相等,可使用比较运算符,用两个等号(== )表示。

>>> "foo" == "foo"
True
>>> "foo" == "bar"
False

is 相同运算符

这个运算符很有趣,其作用看似与 == 一样,但实际上并非如此。在和 None 值对比时建议使用 is 而不是相等运算符。

>>> x = y = [1, 2, 3]
>>> z = [1, 2, 3]
>>> x == y
True
>>> x == z
True
>>> x is y
True
>>> x is z
False

在前几个示例中,看不出什么问题,但最后一个示例的结果很奇怪:x 和 z 相等,但 x is z 的结果却为 False。为何会这样呢?因为 is 检查两个对象是否相同(而不是相等)。变量 x 和 y 指向同一个列表,而 z 指向另一个列表。这两个列表虽然相等,但并非同一个对象(两个变量指向的内存值并不一样)。

总之,== 用来检查两个对象是否相等,而 is 用来检查两个对象是否相同(是同一个对象)。

Note

不要将 is 用于数和字符串等不可变的基本值。鉴于 Python 在内部处理这些对象的方式,这样做的结果是不可预测的。

in 成员资格运算符

运算符 in 与其他比较运算符一样,也可用于条件表达式中。

>>> 'a' in 'abc'
True
>>> 'a' in ('a', 'b', 'c')
True

字符串或序列的比较

字符串是根据字符的字母排列顺序进行比较的。

>>> "alpha" < "beta"
True

虽然基于的是字母排列顺序,但字母都是 Unicode 字符,它们是按码点排列的。实际上,字符是根据顺序值排列的。要获悉字母的顺序值,可使用内置函数 ord() 。这个函数的作用与函数 chr() 相反:

>>> ord('a')
97
>>> ord('b')
98
>>> chr(98)
'b'

这种方法既合理又一致,但可能与排序的方式相反。例如,涉及大写字母时,排列顺序就可能与想要的结果不同。

>>> "a" < "B"
False

>>> "a".lower() < "B".lower()
True

>>> 'FnOrD'.lower() == 'Fnord'.lower()
True

其他序列的比较方式与此相同,但这些序列包含的元素可能不是字符,而是其他类型的值。如果序列的元素为其他序列,将根据同样的规则对这些元素进行比较。

>>> [1, 2] < [2, 1]
True

>>> [2, [1, 4]] < [2, [1, 5]]
True

布尔运算符 and、or、not

当需要检查多个条件时,就需要用到 and、or、not 等运算符。假设要编写一个程序,让它读取一个数,并检查这个数是否位于 1 和 10 之间。

number = int(input('Enter a number between 1 and 10: '))
if number <= 10:
    if number >= 1:
        print('Great!')
    else:
        print('Wrong!')
else:
    print('Wrong!')

这样做有点笨拙,因为输入了 print('Wrong!') 两次(重复劳动可不是好事)。

number = int(input('Enter a number between 1 and 10: '))
if number <= 10 and number >= 1:
    print('Great!')
else:
    print('Wrong!')

Note

通过使用链式比较 1 <= number <= 10 可进一步简化这个示例,通常就应该这样做。

运算符 and 是一个布尔运算符。它接受两个真值,并在这两个值都为真时返回真,否则返回假。还有另外两个布尔运算符:or 和 not。通过使用这三个运算符,能以任何方式组合真值。

if ((cash > price) or customer_has_good_credit) and not out_of_stock:
    give_goods()

短路逻辑和条件表达式

布尔运算符的真值表

表达式

True and True

True

True and False

False

False and True

False

False and False

False

True or True

True

True or False

True

False or True

True

False or False

False

not True

False

not False

True

布尔运算符常被称为逻辑运算符,在有些情况下将“绕过”第二个值。例如,当使用 x and y 时,如果 x 为假,这个表达式将立即返回假,而不关心 y。实际上,如果 x 为假,这个表达式将返回 x,否则返回 y。这种行为称为短路逻辑(或者延迟求值)。

对于运算符 or,情况亦如此。在表达式 x or y 中,如果 x 为真,就返回 x,否则返回 y。请注意,这意味着位于布尔运算符后面的代码(如函数调用)可能根本不会执行。像下面这样的代码就利用了这种行为:

name = input('Please enter your name: ') or '<unknown>'

如果没有输入名字,上述 or 表达式的结果将为 ‘<unknown>’ 。通常应该使用条件表达式,而不要耍这样的短路花样,不过前面这样的语句确实有其用武之地。