Почему "нет (правда) в [False, True]" возвращается False?

Если я это сделаю:

>>> False in [False, True]
True

Возвращает True. Просто потому, что False находится в списке.

Но если я это сделаю:

>>> not(True) in [False, True]
False

Возвращает False. Если not(True) равно False:

>>> not(True)
False

Почему?

Ответ 1

Приоритет оператора 2.x, 3.x. Приоритет not ниже, чем у in. Так что это эквивалентно:

>>> not ((True) in [False, True])
False

Это то, что вы хотите:

>>> (not True) in [False, True]
True

Как указывает @Ben: рекомендуется никогда не писать not(True), предпочитайте not True. Первый делает его похожим на вызов функции, в то время как not является оператором, а не функцией.

Ответ 2

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        

Ответ 3

Приоритет оператора. in связывается сильнее, чем not, поэтому ваше выражение эквивалентно not((True) in [False, True]).

Ответ 4

Все о приоритет оператора (in сильнее, чем not). Но его можно легко скорректировать, добавив круглые скобки в нужное место:

(not(True)) in [False, True]  # prints true

записывания:

not(True) in [False, True]

то же самое:

not((True) in [False, True])

который выглядит, если True находится в списке и возвращает "нет" результата.

Ответ 5

Он оценивается как not True in [False, True], который возвращает False, потому что True находится в [False, True]

Если вы попробуете

>>>(not(True)) in [False, True]
True

Вы получите ожидаемый результат.

Ответ 6

Наряду с другими ответами, в которых упоминалось, что приоритет 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.

Можно предположить, что центральный объект будет разделен между двумя операциями и другими объектами (в этом случае False).

Обратите внимание, что это также верно для всех сравнений, включая тесты на членство и операции проверки идентичности, следующие операнды:

in, not in, is, is not, <, <=, >, >=, !=, ==

Пример:

>>> 1 in [1,2] == True
False

Другим известным примером является диапазон номеров:

7<x<20

который равен:

7<x and x<20   

Ответ 7

Посмотрите на него как на проверку проверки сдерживания коллекции: [False, True] - это список, содержащий некоторые элементы.

Выражение True in [False, True] возвращает True, поскольку True - это элемент, содержащийся в списке.

Следовательно, not True in [False, True] дает результат "boolean contrast", not из приведенного выше выражения (без каких-либо круглых скобок для сохранения приоритета, поскольку in имеет больший приоритет, чем оператор not). Следовательно, not True приведет к False.

С другой стороны, (not True) in [False, True], равно False in [False, True], который True (False содержится в списке).

Ответ 8

Чтобы уточнить некоторые другие ответы, добавление круглых скобок после унарного оператора не изменяет его приоритет. 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) - это точно то же самое.

Ответ 9

Здесь - документация о приоритете операторов.

in binds tighter than not

Таким образом, это послужит цели

>>> (not True) in [False, True]
True