Python 中的不等式和括号
Inequalities and Parenthesis in Python
所以在 python 中,可以很容易地检查真值条件,并在括号中优先考虑真值条件的顺序,例如这些很容易理解:
>>> 3 > 2
True
>>> (3 > 2) is True
True
但是这些是什么意思,我无法理解为什么它们的逻辑 return False/True:
>>> 3 > 2 is True
False
>>> 3 > (2 is True)
True
>>> 5 < 3 is False > 2 is True
False
>>> 5 < 3 is False is True > 2 is True
False
>>> 3 < 5 is True is True > 2 is True
False
>>> 3 < 5 is True is True > 2 is True is not False is True
False
>>> 3 < 5 is True is (True > 2 is True is not False) is True
False
>>> 3 < 5 is True is (True > (2 is True) is not False) is True
False
>>> (3 < 5 is True is True) > 2 is (True is not False is True)
False
我知道这些不是 pythonic 条件,但 我应该如何理解它们?还是从左到右?
还是is True
or/andis False
当总统?
您可以使用 dis
模块分析每个案例,以弄清楚到底发生了什么。例如:
In [1]: import dis
In [2]: def test():
...: return 3 > 2 is True
...:
In [3]: dis.dis(test)
2 0 LOAD_CONST 1 (3)
3 LOAD_CONST 2 (2)
6 DUP_TOP
7 ROT_THREE
8 COMPARE_OP 4 (>)
11 JUMP_IF_FALSE_OR_POP 21
14 LOAD_GLOBAL 0 (True)
17 COMPARE_OP 8 (is)
20 RETURN_VALUE
>> 21 ROT_TWO
22 POP_TOP
23 RETURN_VALUE
这意味着堆栈在每一步之后看起来像这样:
0: 3
3: 3 2
6: 3 2 2
7: 2 3 2
8: 2 True
11: 2
14: 2 True
17: False (comparison was: "2 is True")
20: (False is returned)
对我来说,老实说,这看起来像是 Python 中的一个错误。也许有一些很好的解释为什么会发生这种情况,但我会向上游报告。
只是以等效的方式重写它,代码就是:
if 3 > 2:
if 2 is True:
return True
return False
编辑:也许它实际上有某种奇怪的意义。考虑检查链式不等式的工作原理:
3 > 2 > 1 == 3 > 2 and 2 > 1
如果概括为:
x op1 y op2 z == x op1 y and y op2 z
这可以解释结果。
Edit2:这实际上与文档相符。查看链式比较:https://docs.python.org/2/reference/expressions.html#not-in
comparison ::= or_expr ( comp_operator or_expr )*
comp_operator ::= "<" | ">" | "==" | ">=" | "<=" | "<>" | "!="
| "is" ["not"] | ["not"] "in"
is
被认为与 >
一样好,因此应用了多重比较的标准扩展。
其他的对比现在应该清楚了。唯一需要的奇怪的新细节是:True == 1
、False == 0
,所以 3 > (2 is True)
中的 3 > False
。大多数其他人可以用扩展来解释。例如:
5 < 3 is False > 2 is True == False
(5 < 3) and (3 is False) and (False > 2) and (2 is True) == False
首先,您可能需要一点作弊 sheet 才能了解 order of evaluation。大多数这些运算符都在同一个括号中,因此从左到右计算。有了这些知识,这些例子就可以翻译成它们的 "real" 意思:
(3 < 5 is True is True) > 2 is (True is not False is True)
等价于:(实际上没有__is__
和__not__
,因为那些是不能重载的关键字,只是为了说明)
(3.__lt__(5).__is__(True).__is__(True)).__gt__(2).__is__(True.__is__(False).__not__().__is__(True))
我可能会省去描述的一些细节 here。好处是您(希望)永远不会编写如此复杂的表达式,以至于您需要查看文档才能知道它的作用。
编辑:没关系,这种方式不能用于比较。比较得到比较 "all together pairwise",就像 viraptor 的回答中描述的那样。
Boolean
python 中的类型是 int
的子类型。所以 True
实际上是 1 而 False
实际上是 0.
Python中的所有比较操作具有相同的优先级(>
、<
、>=
、<=
、==
、!=
, is [not]
, [not] in
).
Comparisons can be chained arbitrarily, e.g., x < y <= z
is equivalent to x < y and y <= z
, except that y is evaluated only once (but in both cases z is not evaluated at all when x < y
is found to be false).
Formally, if a
, b
, c
, ..., y
, z
are expressions and op1
, op2
, ..., opN
are comparison operators, then a op1 b op2 c ... y opN z
is equivalent to a op1 b and b op2 c and ... y opN z
, except that each expression is evaluated at most once.
所以在 python 中,可以很容易地检查真值条件,并在括号中优先考虑真值条件的顺序,例如这些很容易理解:
>>> 3 > 2
True
>>> (3 > 2) is True
True
但是这些是什么意思,我无法理解为什么它们的逻辑 return False/True:
>>> 3 > 2 is True
False
>>> 3 > (2 is True)
True
>>> 5 < 3 is False > 2 is True
False
>>> 5 < 3 is False is True > 2 is True
False
>>> 3 < 5 is True is True > 2 is True
False
>>> 3 < 5 is True is True > 2 is True is not False is True
False
>>> 3 < 5 is True is (True > 2 is True is not False) is True
False
>>> 3 < 5 is True is (True > (2 is True) is not False) is True
False
>>> (3 < 5 is True is True) > 2 is (True is not False is True)
False
我知道这些不是 pythonic 条件,但 我应该如何理解它们?还是从左到右?
还是is True
or/andis False
当总统?
您可以使用 dis
模块分析每个案例,以弄清楚到底发生了什么。例如:
In [1]: import dis
In [2]: def test():
...: return 3 > 2 is True
...:
In [3]: dis.dis(test)
2 0 LOAD_CONST 1 (3)
3 LOAD_CONST 2 (2)
6 DUP_TOP
7 ROT_THREE
8 COMPARE_OP 4 (>)
11 JUMP_IF_FALSE_OR_POP 21
14 LOAD_GLOBAL 0 (True)
17 COMPARE_OP 8 (is)
20 RETURN_VALUE
>> 21 ROT_TWO
22 POP_TOP
23 RETURN_VALUE
这意味着堆栈在每一步之后看起来像这样:
0: 3
3: 3 2
6: 3 2 2
7: 2 3 2
8: 2 True
11: 2
14: 2 True
17: False (comparison was: "2 is True")
20: (False is returned)
对我来说,老实说,这看起来像是 Python 中的一个错误。也许有一些很好的解释为什么会发生这种情况,但我会向上游报告。
只是以等效的方式重写它,代码就是:
if 3 > 2:
if 2 is True:
return True
return False
编辑:也许它实际上有某种奇怪的意义。考虑检查链式不等式的工作原理:
3 > 2 > 1 == 3 > 2 and 2 > 1
如果概括为:
x op1 y op2 z == x op1 y and y op2 z
这可以解释结果。
Edit2:这实际上与文档相符。查看链式比较:https://docs.python.org/2/reference/expressions.html#not-in
comparison ::= or_expr ( comp_operator or_expr )*
comp_operator ::= "<" | ">" | "==" | ">=" | "<=" | "<>" | "!="
| "is" ["not"] | ["not"] "in"
is
被认为与 >
一样好,因此应用了多重比较的标准扩展。
其他的对比现在应该清楚了。唯一需要的奇怪的新细节是:True == 1
、False == 0
,所以 3 > (2 is True)
中的 3 > False
。大多数其他人可以用扩展来解释。例如:
5 < 3 is False > 2 is True == False
(5 < 3) and (3 is False) and (False > 2) and (2 is True) == False
首先,您可能需要一点作弊 sheet 才能了解 order of evaluation。大多数这些运算符都在同一个括号中,因此从左到右计算。有了这些知识,这些例子就可以翻译成它们的 "real" 意思:
(3 < 5 is True is True) > 2 is (True is not False is True)
等价于:(实际上没有__is__
和__not__
,因为那些是不能重载的关键字,只是为了说明)
(3.__lt__(5).__is__(True).__is__(True)).__gt__(2).__is__(True.__is__(False).__not__().__is__(True))
我可能会省去描述的一些细节 here。好处是您(希望)永远不会编写如此复杂的表达式,以至于您需要查看文档才能知道它的作用。
编辑:没关系,这种方式不能用于比较。比较得到比较 "all together pairwise",就像 viraptor 的回答中描述的那样。
Boolean
python 中的类型是 int
的子类型。所以 True
实际上是 1 而 False
实际上是 0.
Python中的所有比较操作具有相同的优先级(>
、<
、>=
、<=
、==
、!=
, is [not]
, [not] in
).
Comparisons can be chained arbitrarily, e.g.,
x < y <= z
is equivalent tox < y and y <= z
, except that y is evaluated only once (but in both cases z is not evaluated at all whenx < y
is found to be false).Formally, if
a
,b
,c
, ...,y
,z
are expressions andop1
,op2
, ...,opN
are comparison operators, thena op1 b op2 c ... y opN z
is equivalent toa op1 b and b op2 c and ... y opN z
, except that each expression is evaluated at most once.