2

The canonical question on the difference between not x in y and x not in y states that these two are equivalent in implementation (in CPython). The operator precedence rules state that the Boolean not has higher precedence than in. So shouldn't not x in y be implemented to be equivalent to (not x) in y?

Consider

x = False
list2 = ['a']
not x in list2
Out[19]: True
(not x) in list2
Out[20]: False

I would have expected second last statement to be False, if I'm understanding the precedence rules correctly.

sshashank124
  • 31,495
  • 9
  • 67
  • 76
flow2k
  • 3,999
  • 40
  • 55
  • The answer to your question is in the question you linked. Last paragraph of the accepted answer: "the form `not a in b` is special cased so that it's not actually using the general operator. This makes `not a in b` literally the same expression as `a not in b`" – sshashank124 Jan 11 '20 at 09:45
  • 3
    Also you have read the table wrong, it lists operators from **least to most** order of precedence, therefore `not x in y` is the same as `not (x in y)` and not `(not x) in y` as you claim. Whew, too many nots in that sentence – sshashank124 Jan 11 '20 at 09:50

1 Answers1

4

Rather subtle but if you look in the official documentation that you linked to, you will see that "not in" is its own operator, which has a higher precedence than "not" and the same precedence as "in".

Your mistake is probably coming from reading the operator precedence rules the wrong way around. As it currently stands, the lowest precedence comes higher up in the list. So not x in list2 is equvalent to not (x in list2).

Your last assumption will, because you have surrounded it with parentheses, first evaluate not x to a boolean (False), then check if that boolean is in the list (which it is not, there's only a string in the list), and return False.

ilmarinen
  • 4,557
  • 3
  • 16
  • 12