逻辑值检测¶
任何对象都可以进行逻辑值的检测,以便在 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>’ 。通常应该使用条件表达式,而不要耍这样的短路花样,不过前面这样的语句确实有其用武之地。