开发者

Are "not in" and "is not" both operators? If so, are they in any way different than "not x in.." and "not x is.."?

I've always preferred these:

not 'x' in 'abc'
not 'x' is 'a'

(assuming, of course that everyone knows in and is out-prioritize not -- I probably should use parentheses) over the more (English) grammatical:

'x' not in 'abc'
'x' is not 'a'

but didn't bother to think why until I realized they do not make syntactical sense

'x' == not 'a'
'x' not == 'a'

both of course throw a syntax error.

so I figured they were both two-word operators. However, the documentation only references is not and makes no mention of not in as an operator. Am I perhaps misinterpreting the syntax?

If they both are operators, then are they at all different (even subtlety) from their non-grammatical counterparts?

If they are the same, then why do they exist? It seems to be impious to the Zen of Python (.."one -- and preferably only one -- obvious way"..)

I apologize if this has been discussed to death alre开发者_如何学运维ady, I just had little luck finding it with search terms like "is not".


It's easy to check if there's any difference, with the dis module:

>>> dis.dis(compile('not a in b','','exec'))
  1           0 LOAD_NAME                0 (a)
              3 LOAD_NAME                1 (b)
              6 COMPARE_OP               7 (not in)
              9 POP_TOP             
             10 LOAD_CONST               0 (None)
             13 RETURN_VALUE        
>>> dis.dis(compile('a not in b','','exec'))
  1           0 LOAD_NAME                0 (a)
              3 LOAD_NAME                1 (b)
              6 COMPARE_OP               7 (not in)
              9 POP_TOP             
             10 LOAD_CONST               0 (None)
             13 RETURN_VALUE        

See? The awkward first form (who often confuses those who can't immediately tell the relative priority of not and in operators) gets compiled into exactly the same bytecode as the can't-confuse-anybody second for, with the single not in operator. Similarly:

>>> dis.dis(compile('not a is b','','exec'))
  1           0 LOAD_NAME                0 (a)
              3 LOAD_NAME                1 (b)
              6 COMPARE_OP               9 (is not)
              9 POP_TOP             
             10 LOAD_CONST               0 (None)
             13 RETURN_VALUE        
>>> dis.dis(compile('a is not b','','exec'))
  1           0 LOAD_NAME                0 (a)
              3 LOAD_NAME                1 (b)
              6 COMPARE_OP               9 (is not)
              9 POP_TOP             
             10 LOAD_CONST               0 (None)
             13 RETURN_VALUE        

both these forms -- the goofy, confusing first one, and the elegant second one -- compare to exactly the same code, and both use the is not operator.

Of course there's no good reason to use the forms that can confuse the reader (unless you like to set traps for those who read your code!-), but in terms of execution semantics and speed there's no difference whatsoever.


From the python 2.6.4 docs at: http://docs.python.org/reference/expressions.html >

The operator not in is defined to have the inverse true value of in.

The operators is and is not test for object identity: x is y is true if and only if x and y are the same object. x is not y yields the inverse truth value.

eg: "x not in y" is exactly the same as "not x in y" and "x is not y" is the same as "not x is y".

"x not == y" doesn't parse, but "x != y" does, so there's an equivalence there too ...

HTH.


The remainder of your question has been answered above, but I'll address the last question: the Zen of Python bit.

"There should only be one way to do it" isn't mean't in a mathematical sense. If it were, there'd be no != operator, since that's just the inversion of ==. Similarly, no and and or --- you can, after all, just use a single nand command. There is a limit to the "one way" mantra: there should only be one high-level way of doing it. Of course, that high-level way can be decomposed --- you can write your own math.tan, and you never need to use urllib --- socket is always there for you. But just as urllib.open is a higher-level encapsulation of raw socket operations, so not in is a higher-level encapsulation of not and in. That's a bit banal, you might say. But you use x != y instead of not (x == y).


Your documentation reference is nothing to do with syntax. Try this. Both is not and not in are two-word operators.


x in a tests whether the element x is in a (which in this case would probably be a list or a string or some such) and returns True if it is.

x not in a is similar, but returns False if x is in a.

On the other hand, x is not a is analogous to x != a and not x is a.

And like you said, x == not 5 will give you an error of sorts

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜