如何检查 Python 中的真值?有三种方法检查是否True
一种"坏"方式:if variable == True:
另一种"坏"方式:if variable is True:
比较好的方式,建议即是在PEP8的编程建议:if variable:
"坏"的方式不仅看起来复杂,而且速度较慢。让我们使用一个简单的测试:
$python -m timeit -s "variable=False" "if variable == True: pass"
10000000 loops, best of 5: 24.9 nsec per loop
$python -m timeit -s "variable=False" "if variable is True: pass"
10000000 loops, best of 5: 17.4 nsec per loop
$python -m timeit -s "variable=False" "if variable: pass"
20000000 loops, best of 5: 10.9 nsec per loop
使用速度比 (17.4/10.9≈1.596) 慢 60% 左右, 但使用速度慢 120%(24.9/10.9≈ 2.284)!不管 是实际还是 - 性能差异是相似的(如果是 ,则所有三个方案都会稍微慢一些)。isif variable==variableTrueFalsevariableTrue
同样,我们可以检查变量是否未使用以下方法之一:True
if variable != True: ("坏")
if variable is not True: ("坏")
if not variable:(好)
$python -m timeit -s "variable=False" "if variable != True: pass"
10000000 loops, best of 5: 26 nsec per loop
$python -m timeit -s "variable=False" "if variable is not True: pass"
10000000 loops, best of 5: 18.8 nsec per loop
$python -m timeit -s "variable=False" "if not variable: pass"
20000000 loops, best of 5: 12.4 nsec per loop
if not variable赢。 其它速度慢 50%(18.8/12.4≈1.516),并且需要两倍长(26/12.4≈2.016)。is not!=
和 版本执行速度更快,读取速度更快。它们是常见的习惯用语,您经常会在 Python(或其他编程语言)中看到。if variableif not variable
"真实" 和 "虚假"
为什么我一直把"坏" 放在引号里?这是因为"坏"方式并不总是不好的(只有当你想比较布尔值时,它才是错误的,如PEP8中所示)。有时,您有意使用其他比较之一。
在 Python(和许多其他语言)中,有 ,并且有真理值。也就是说,值被解释为运行 。同样,存在 ,并且存在虚假值(从 返回的值)。空列表 ()、字符串 ()、字典 () 和 0都是伪造的,但它们不是严格意义上的。TrueTruebool(variable)FalseFalsebool(variable)[]""{}NoneFalse
有时你需要区分 / 和真理/虚假的价值观。如果代码在传递空列表时应以一种方式运行,而在传递 时,则不能使用 。TrueFalseFalseif not value
查看以下方案:
def process_orders(orders=None):
if not orders:
# There are no orders, return return
else:
# Process orders ...
我们有一个函数来处理一些订单。如果没有订单,我们想返回而不做任何事情。否则,我们要处理现有订单。
我们假设如果没有订单,则参数设置为 。但是,如果 是一个空列表,我们也返回没有任何操作!也许可以接收空列表, 因为有人只是更新过去订单的计费信息?或者,有一个空列表意味着系统中存在错误。我们应该在用空订单填满数据库之前抓住那个错误!无论空列表的原因是什么,上面的代码都会忽略它。我们可以通过更仔细地调查参数来修复它:ordersNoneordersorders
def process_orders(orders=None):
if orders is None:
# orders is None, return return
elif orders == []:
# Process empty list of orders ...
elif len(orders) > 0:
# Process existing orders ...
这同样适用于真理价值观。如果你的代码应该以不同的方式工作,比比,值,我们不能使用。我们应该用比较数字 () 和比较 ()。听起来很令人困惑吗?让我们来看看 和 的区别。True1if variable==if variable == 1isTrueif variable is Trueis==
is检查标识,检查值==
运算符比较对象的标识。如果两个变量相同,则意味着它们指向同一个对象(内存中的相同位置)。它们具有相同的 ID(您可以使用ID() 函数检查)。is
运算符比较值。它检查一个变量的值是否等于其他变量的值。==
Python 中某些对象是唯一的,例如 或 。每次向 分配变量时,它指向与分配给 的其他变量相同的对象。但是,每次创建新列表时,Python 都会创建一个新对象:NoneTrueFalseTrueTrueTrue
>>> a = True
>>> b = True
>>> a is b
True
# Variables that are identical are always also equal!>>> a == b
True
# But>>> a = [1,2,3]
>>> b = [1,2,3]
>>> a is b
False # Those lists are two different objects>>> a == b
True # Both lists are equal (contain the same elements)
了解 和 的区别很重要。如果您认为它们的工作方式相同,则代码中可能最终出现奇怪的错误:is==
a = 1
# This will print 'yes'if a is 1:
print('yes')
b = 1000
# This won't!if b is 1000:
print('yes')
在上面的示例中,第一个代码块将打印"是",但第二个不会。这是因为 Python 执行一些微小的优化,并且小整数共享相同的 ID(它们指向同一个对象)。每次分配给新变量时,它指向同一个对象。但是,当您分配给变量时,它会创建一个新对象。如果我们使用 ,那么一切都将工作如预期。111000b == 1000
结论
总结一下:
要检查变量是否等于 True/False(并且不必区分 / 和真/假值),请使用 或 。这是最简单和最快的方法。TrueFalseif variableif not variable
如果要检查变量是否显式为"真"或"假"(并且不是真/假),请使用 ()。isif variable is True
如果要检查变量是否等于 0 或列表是否为空,请使用 或 。if variable == 0if variable == []