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

可紊 提交于 2019-12-13 04:55:33

问题


I have a certain string k that may or many not a key of a dict reversedmapping, and another dict spendDict where it may also be a key.

Why does the following check succeed (i.e. run to completion), for a value of k that is not a key of reversedmapping:

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

whereas I get a KeyError (for k) when I change it to logical AND:

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

And how do I rewrite the AND variant to avoid the KeyError?


回答1:


If (k not in reversedmapping) is True, then

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

short-circuits, which means it returns True without evaluating

(reversedmapping[k] not in spendDict)

Since True or anything is True.

In contrast,

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

must evaluate both parts before Python can determine that the total expression is True.


If (k not in reversedmapping) is True, then reversedmapping[k] will raise KeyError.

If (k not in reversedmapping) is False, then the expression short-circuits and returns False since False and anything is False.

So

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

will always either return False or raise a KeyError. There is no situation under which it could return True. Both conditions can not be True.




回答2:


Python's and and or are short-circuit operators. That means they only evaluate both parts of the expression when the answer isn't clear from the left hand operand. For and, if the first operand evaluates to False, then there's no way the result can be true, so the second operand isn't evaluated. For or, it's the opposite - if the first operand evaluates to True, the result is True no matter what the second operand is.

In your case, if k isn't in reversedmapping, or sees a true value on its left hand side and returns without evaluating the right hand sids, so no KeyError. If you use an and and the first test is true (k is not in reversedmapping), it's still forced to evaluate the second operand to see if they're both true, so it tries to pull k from the dict and throws an exception.



来源:https://stackoverflow.com/questions/31331029/why-does-a-keyerror-get-thrown-in-logical-and-but-not-in-a-logical-or

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!