Logical not in Python

1.2k views Asked by At

I am seeing code like this:

if not n >= 0:
        raise ValueError("n must be >= 0")

from a snippet in the docs.

Why doesn't it simply use?

if n < 0:

I am new to Python and I suppose they are the same. Is that true?

2

There are 2 answers

0
Prune On BEST ANSWER

The comments and prior answer cover the coding style. There's also one important functional point: NaN

NaN (Not-a-Number) values arise from certain data operations that produce an unacceptable result. The hardware or method documentation will specify when NaN is returned. This often accompanies an exception, but you may see such a value if you have a deeper application that handles the exception and decides to live with the result. Big Data frames often do this.

The functional point is that a NaN value will fail any comparison test. For instance, a simple way to check for NaN is to compare the value against itself:

if n == n:
    print "legal"
else"
    print "NaN"

Note that you cannot reverse the logic with n != n, as that will also evaluate to False.

Thus, there is a functional difference between the two comparisons.

if not n >= 0:

will throw the exception if n is NaN; the n < 0 implementation will not.

0
ShadowRanger On

I assume because it was trying to describe the operation in English, rather than code. "If n is not greater than or equal to zero" vs. "If n is less than 0", the former is describing the desired values and saying if it doesn't get them, it's an error, the latter is describing the values it doesn't want, which is less "friendly", at least IMO (it hardly matters I'll admit; I wouldn't care if code used either one).

In practice, they boil down to the same thing (assuming the rich comparisons for n with an int form a total ordering relationship, with no tricksiness). Even CPython, which has a terrible byte code optimizer, recognizes a not like this and just switches between byte code instructions for POP_JUMP_IF_TRUE and POP_JUMP_IF_FALSE, which have equivalent overhead, so it's not doing any extra work.