Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

"x not in y" or "not x in y"

When testing for membership, we can use:

x not in y 

Or alternatively:

not x in y 

There can be many possible contexts for this expression depending on x and y. It could be for a substring check, list membership, dict key existence, for example.

  • Are the two forms always equivalent?
  • Is there a preferred syntax?
like image 735
wim Avatar asked Jan 05 '12 06:01

wim


People also ask

Is not in vs not in Python?

Python 'in' operator is used to check if a value exists in a sequence or not. It evaluates to True if it finds the variable in the specified sequence and False otherwise. Python 'not in' operator evaluates to True if it does not finds a variable in the specified sequence and False otherwise.


1 Answers

They always give the same result.

In fact, not 'ham' in 'spam and eggs' appears to be special cased to perform a single "not in" operation, rather than an "in" operation and then negating the result:

>>> import dis  >>> def notin():     'ham' not in 'spam and eggs' >>> dis.dis(notin)   2           0 LOAD_CONST               1 ('ham')               3 LOAD_CONST               2 ('spam and eggs')               6 COMPARE_OP               7 (not in)               9 POP_TOP                           10 LOAD_CONST               0 (None)              13 RETURN_VALUE      >>> def not_in():     not 'ham' in 'spam and eggs' >>> dis.dis(not_in)   2           0 LOAD_CONST               1 ('ham')               3 LOAD_CONST               2 ('spam and eggs')               6 COMPARE_OP               7 (not in)               9 POP_TOP                           10 LOAD_CONST               0 (None)              13 RETURN_VALUE      >>> def not__in():     not ('ham' in 'spam and eggs') >>> dis.dis(not__in)   2           0 LOAD_CONST               1 ('ham')               3 LOAD_CONST               2 ('spam and eggs')               6 COMPARE_OP               7 (not in)               9 POP_TOP                           10 LOAD_CONST               0 (None)              13 RETURN_VALUE          >>> def noteq():     not 'ham' == 'spam and eggs' >>> dis.dis(noteq)   2           0 LOAD_CONST               1 ('ham')               3 LOAD_CONST               2 ('spam and eggs')               6 COMPARE_OP               2 (==)               9 UNARY_NOT                         10 POP_TOP                           11 LOAD_CONST               0 (None)              14 RETURN_VALUE       

I had thought at first that they always gave the same result, but that not on its own was simply a low precedence logical negation operator, which could be applied to a in b just as easily as any other boolean expression, whereas not in was a separate operator for convenience and clarity.

The disassembly above was revealing! It seems that while not obviously is a logical negation operator, 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, rather than merely an expression that results in the same value.

like image 181
Ben Avatar answered Nov 10 '22 07:11

Ben