Reputation: 362786
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.
Upvotes: 123
Views: 22337
Reputation: 350300
They are identical in meaning, but the pycodestyle Python style guide checker (formerly called pep8) prefers the not in
operator in rule E713:
E713: test for membership should be
not in
See also "Python if x is not None
or if not x is None
?" for a very similar choice of style.
Upvotes: 12
Reputation: 60594
Others have already made it very clear that the two statements are, down to a quite low level, equivalent.
However, I don't think that anyone yet has stressed enough that since this leaves the choice up to you, you should
And not necessarily as readable as possible to anyone, even if that's of course a nice thing to aim for. No, make sure the code is as readable as possible to you, since you are the one who is the most likely to come back to this code later and try to read it.
Upvotes: 2
Reputation: 71495
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.
Upvotes: 131
Reputation: 106440
Syntactically they're the same statement. I would be quick to state that 'ham' not in 'spam and eggs'
conveys clearer intent, but I've seen code and scenarios in which not 'ham' in 'spam and eggs'
conveys a clearer meaning than the other.
Upvotes: 0
Reputation: 129001
The operator
not in
is defined to have the inverse true value ofin
.
not in
is preferred because it is more obvious and they added a special case for it.Upvotes: 25
Reputation: 798706
In Python, there is no difference. And there is no preference.
Upvotes: 1