Почему "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) это то же самое.