为什么Python不会为以下情况抛出索引错误?

时间:2013-12-27 17:02:28

标签: python algorithm python-2.7 if-statement boolean

我在涉及布尔操作的“if”条件语句中遇到了这个Python场景。只要条件中存在索引错误,Python就会将其视为False,而不是抛出索引错误。这种行为的原因是什么?

示例场景:

lst = [3, 4, 23, 5, 25, 76]
n = len(lst)
if n < 5 and lst[6] > lst[2]:
    print True
print False

输出:

False

正如您所看到的,为什么Python返回 False ?,我原以为它会抛出索引错误。有人可以解释幕后发生的事情。

4 个答案:

答案 0 :(得分:10)

在你的例子中,n = 6,所以n不是&lt; 5. Python短路布尔逻辑,因此跳过了表达式的后半部分。

答案 1 :(得分:4)

Python中的

and使用short-circuit evaluation,这意味着如果它的第一个参数求值为false(如n < 5那样),那么第二个参数将保持未评估状态,因为整个表达式必须在那时是假的。因此,永远不会评估lst[6] > lst[2]

现在让我们试试&短路:

>>> lst = [3, 4, 23, 5, 25, 76]
>>> n = len(lst)
>>> if (n < 5) & (lst[6] > lst[2]):
...     pass
... 
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
IndexError: list index out of range

这给出了您期望的结果。

答案 2 :(得分:2)

当结果已知时,Python会尽快停止评估条件。在您的示例中,n < 5False,因此在连词(and)的情况下,不需要评估第二部分 - 它与评估的内容无关,整个表达式是目前已知为False

如果第一个条件为or,则True个表达式也是如此,因此:

if not (n >= 5 or lst[6] <= lst[2]):

也不会扔。

此机制称为Short-circuit evaluation

答案 3 :(得分:1)

and语句中使用if就像编写两个if语句,一个在另一个中:

if n < 5:
    if lst[6] > lst[2]:
        print True

在这种情况下很明显,如果if不小于5,第二个n不会引发错误:永远不会执行它。由于其他人已经描述过的短路功能,将它们组合在一个if中具有完全相同的行为。

顺便说一句,or的“长”方式是这样的:

# if x == 0 or 1/x > 0.01: print True
if x == 0:
    print True
elif 1/x > 0.01:
    print True

这里我们通过仅计算1/x(如果x不为零)来避免除零(错误)。这同样适用于单ifor。由于x == 0在这种情况下是正确的,因此通过评估该术语可以知道表达式的真值,因此无需评估第二项。