为什么 KeyError 会在逻辑 AND 中抛出,但不会在逻辑 OR 中抛出

Why does a KeyError get thrown in logical AND but not in a logical OR

我有一个字符串 k 可能是或很多不是字典的键 reversedmapping,还有另一个字典 spendDict 它也可能是键。

为什么以下检查成功(即 运行 完成),因为 k 的值不是 reversedmapping 的键:

if (k not in reversedmapping) or (reversedmapping[k] not in spendDict)

而当我将其更改为逻辑 AND:

时,我得到了 KeyError(对于 k)

if (k not in reversedmapping) and (reversedmapping[k] not in spendDict):

以及如何重写 AND 变量以避免 KeyError?

如果(k not in reversedmapping)True,那么

(k not in reversedmapping) or (reversedmapping[k] not in spendDict)

short-circuits,这意味着它 returns True 没有计算

(reversedmapping[k] not in spendDict)

因为 True or anythingTrue

相比之下,

 (k not in reversedmapping) and (reversedmapping[k] not in spendDict)

必须先对两个部分求值,然后 Python 才能确定整个表达式 是 True.


如果(k not in reversedmapping)True,那么reversedmapping[k]会加注 KeyError

如果(k not in reversedmapping)False,则表达式短路 returns False 因为 False and anythingFalse.

所以

(k not in reversedmapping) and (reversedmapping[k] not in spendDict)

将始终 return False 或提出 KeyError。没有情况 它可以 return True两个条件都不能为真。

Python的andorshort-circuit operators。这意味着当左侧操作数的答案不明确时,他们只评估表达式的两个部分。对于 and,如果第一个操作数的计算结果为 False,则结果不可能为真,因此不计算第二个操作数。对于 or,则相反 - 如果第一个操作数的计算结果为 True,无论第二个操作数是什么,结果都是 True

在您的情况下,如果 k 不在 reversedmapping 中,or 会在其左侧看到一个真实值,而 returns 不会评估右侧SIDS,所以没有 KeyError。如果您使用 and 并且第一个测试为真(k 不在 reversedmapping 中),它仍然被迫评估第二个操作数以查看它们是否都为真,所以它尝试从字典中提取 k 并抛出异常。