Почему "not (True) in [False, True]" возвращает False?
если я сделаю это:
>>> False in [False, True]
True
возвращает True
. Просто потому что False
в списке.
но если я это сделаю:
>>> not(True) in [False, True]
False
возвращает False
. Тогда как not(True)
равна False
:
>>> not(True)
False
почему?
8 ответов
приоритет операторов 2.x, 3.x. Приоритет not
меньше, чем in
. Таким образом, это эквивалентно:
>>> not (True in [False, True])
False
это то, что вы хотите:
>>> (not True) in [False, True]
True
как указывает @Ben: рекомендуется никогда не писать not(True)
предпочитаю not True
. Бывшая делает его похожим на вызов функции, в то время как not
является оператором, а не функцией.
not x in y
оценивается как x not in y
вы можете точно увидеть, что происходит, разобрав код. Первый случай работает так, как вы ожидаете:
>>> x = lambda: False in [False, True]
>>> dis.dis(x)
1 0 LOAD_GLOBAL 0 (False)
3 LOAD_GLOBAL 0 (False)
6 LOAD_GLOBAL 1 (True)
9 BUILD_LIST 2
12 COMPARE_OP 6 (in)
15 RETURN_VALUE
второй случай, оценивает True not in [False, True]
, которая составляет False
четко:
>>> x = lambda: not(True) in [False, True]
>>> dis.dis(x)
1 0 LOAD_GLOBAL 0 (True)
3 LOAD_GLOBAL 1 (False)
6 LOAD_GLOBAL 0 (True)
9 BUILD_LIST 2
12 COMPARE_OP 7 (not in)
15 RETURN_VALUE
>>>
то, что вы хотели выразить вместо этого было (not(True)) in [False, True]
, что, как и ожидалось,True
и вы поймете, почему:
>>> x = lambda: (not(True)) in [False, True]
>>> dis.dis(x)
1 0 LOAD_GLOBAL 0 (True)
3 UNARY_NOT
4 LOAD_GLOBAL 1 (False)
7 LOAD_GLOBAL 0 (True)
10 BUILD_LIST 2
13 COMPARE_OP 6 (in)
16 RETURN_VALUE
приоритет операторов. in
связывает более плотно, чем not
, поэтому ваше выражение эквивалентно not((True) in [False, True])
.
это все приоритет операторов (in
сильнее not
). Но это можно легко исправить, добавив скобки в нужном месте:
(not(True)) in [False, True] # prints true
пишем:
not(True) in [False, True]
это то же самое, что:
not((True) in [False, True])
, который выглядит если True
находится в списке и возвращает " не " результата.
он оценивает в not True in [False, True]
, который возвращает False
, потому что True
- в [False, True]
если вы попытаетесь
>>>(not(True)) in [False, True]
True
вы получили ожидаемый результат.
наряду с другими ответами, в которых упоминается приоритет not
меньше in
, на самом деле ваше заявление эквивалентно :
not (True in [False, True])
но обратите внимание, что если вы не отделите свое условие от других, python будет использовать 2 роли (precedence
или chaining
) для того, чтобы отделить это, и в этом случае python использовал приоритет. Кроме того, обратите внимание, что если вы хотите отделить условие, вам нужно поместить все условие в скобки, а не только объект или значение :
(not True) in [False, True]
но, как уже упоминалось, есть еще одна модификация python на операторах, которая является сцепление:
на основе python документация :
обратите внимание, что сравнения, тесты членства и тесты идентичности имеют одинаковый приоритет и имеют слева направо сцепление функции как описано в разделе сравнения.
например результат следующий оператор False
:
>>> True == False in [False, True]
False
потому что python будет связывать операторы следующим образом:
(True == False) and (False in [False, True])
что именно False and True
что это False
.
можно предположить, что центральный объект будет разделен между 2 операциями и другими объектами (в данном случае False).
и обратите внимание, что это также верно для всех сравнений, включая тесты членства и операции тестов идентичности, которые следуют за операндами :
in, not in, is, is not, <, <=, >, >=, !=, ==
пример :
>>> 1 in [1,2] == True
False
другим известным примером является диапазон чисел:
7<x<20
что равно:
7<x and x<20
давайте рассмотрим его как операцию проверки сдерживания коллекции:[False, True]
- Это список, содержащий некоторые элементы.
выражение True in [False, True]
возвращает True
, as True
- элемент, содержащийся в списке.
таким образом, not True in [False, True]
дает "логическое напротив", not
результат приведенного выше выражения (без скобок для сохранения приоритета, как in
имеет больший приоритет, чем not
оператор).
Следовательно,not True
будет результат False
.
С другой стороны, (not True) in [False, True]
, равна False in [False, True]
, которая составляет True
(False
содержится в списке).
чтобы уточнить некоторые из других ответов, добавив скобки после унарный оператор не меняет свой приоритет. not(True)
не делают not
связать более плотно к True
. Это просто избыточный набор скобок вокруг True
. Это почти то же самое, что (True) in [True, False]
. Скобки ничего не делают. Если вы хотите, чтобы привязка была более жесткой, вы должны поставить скобки вокруг всего выражения, то есть как оператор и операнд, т. е., (not True) in [True, False]
.
чтобы увидеть это по-другому, рассмотрим
>>> -2**2
-4
**
связывает более плотно, чем -
, поэтому вы получаете отрицательное из двух квадратов, а не квадрат отрицательных двух (что было бы положительным четыре).
что, если бы вы хотели квадрат отрицательных двух? Очевидно, вы добавите скобки:
>>> (-2)**2
4
однако, не разумно ожидать, что следующее даст 4
>>> -(2)**2
-4
потому что -(2)
это то же самое, что -2
. Скобки абсолютно ничего не делают. not(True)
это то же самое.