Неравенства и скобки в Python
Таким образом, в python, условия истинности могут быть легко проверены и с круглыми скобками это расставляет приоритеты в порядке истинных условий, например, это легко понять:
>>> 3 > 2
True
>>> (3 > 2) is True
True
Но что это значит, я не мог понять логику того, почему они возвращают 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
Я знаю, что это не питонические состояния, но как мне их понимать? Это все еще слева направо?
Или делает is True
и / или is False
принимает президентство?
3 ответа
Вы можете проанализировать каждый из этих случаев с 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
comparison ::= or_expr ( comp_operator or_expr )*
comp_operator ::= "<" | ">" | "==" | ">=" | "<=" | "<>" | "!="
| "is" ["not"] | ["not"] "in"
is
считается столь же хорошим сравнением, как >
, поэтому применяется стандартное расширение для множественных сравнений.
Другие сравнения должны быть ясны сейчас. Единственная странная новая деталь: True == 1
, False == 0
, так 3 > False
в 3 > (2 is True)
, Большинство других можно объяснить с помощью расширений. Например:
5 < 3 is False > 2 is True == False
(5 < 3) and (3 is False) and (False > 2) and (2 is True) == False
Boolean
Тип в Python является подтипом int
, Так True
на самом деле 1 и False
это 0.
Все операции сравнения в Python имеют одинаковый приоритет (>
, <
, >=
, <=
, ==
, !=
, is [not]
, [not] in
).
Сравнения могут быть связаны произвольно, например,
x < y <= z
эквивалентноx < y and y <= z
за исключением того, что y вычисляется только один раз (но в обоих случаях z вообще не оценивается, когдаx < y
оказывается ложным).Формально, если
a
,b
,c
,...,y
,z
выражения иop1
,op2
,...,opN
операторы сравнения, тоa op1 b op2 c ... y opN z
эквивалентноa op1 b and b op2 c and ... y opN z
за исключением того, что каждое выражение оценивается не более одного раза.
Прежде всего, вам, вероятно, понадобится небольшая шпаргалка, чтобы узнать порядок оценки. Большинство из этих операторов находятся в одной скобке и поэтому оцениваются слева направо. С этим знанием примеры могут быть переведены в их "реальное" значение:
(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))
Я мог бы сэкономить некоторые детали, которые описаны здесь. Хорошо, что вы (надеюсь) никогда не пишете такие сложные выражения, что вам нужно проверить документацию, чтобы узнать, что она делает.
РЕДАКТИРОВАТЬ: Неважно, это не работает таким образом с сравнениями. Сравнения сравниваются "все вместе попарно", как описано в ответе Вираптора.