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