How do I get the opposite (negation) of a Boolean in Python? How do I get the opposite (negation) of a Boolean in Python? python python

How do I get the opposite (negation) of a Boolean in Python?


You can just use:

return not bool


The not operator (logical negation)

Probably the best way is using the operator not:

>>> value = True>>> not valueFalse>>> value = False>>> not valueTrue

So instead of your code:

if bool == True:    return Falseelse:    return True

You could use:

return not bool

The logical negation as function

There are also two functions in the operator module operator.not_ and it's alias operator.__not__ in case you need it as function instead of as operator:

>>> import operator>>> operator.not_(False)True>>> operator.not_(True)False

These can be useful if you want to use a function that requires a predicate-function or a callback.

For example map or filter:

>>> lst = [True, False, True, False]>>> list(map(operator.not_, lst))[False, True, False, True]>>> lst = [True, False, True, False]>>> list(filter(operator.not_, lst))[False, False]

Of course the same could also be achieved with an equivalent lambda function:

>>> my_not_function = lambda item: not item>>> list(map(my_not_function, lst))[False, True, False, True]

Do not use the bitwise invert operator ~ on booleans

One might be tempted to use the bitwise invert operator ~ or the equivalent operator function operator.inv (or one of the other 3 aliases there). But because bool is a subclass of int the result could be unexpected because it doesn't return the "inverse boolean", it returns the "inverse integer":

>>> ~True-2>>> ~False-1

That's because True is equivalent to 1 and False to 0 and bitwise inversion operates on the bitwise representation of the integers 1 and 0.

So these cannot be used to "negate" a bool.

Negation with NumPy arrays (and subclasses)

If you're dealing with NumPy arrays (or subclasses like pandas.Series or pandas.DataFrame) containing booleans you can actually use the bitwise inverse operator (~) to negate all booleans in an array:

>>> import numpy as np>>> arr = np.array([True, False, True, False])>>> ~arrarray([False,  True, False,  True])

Or the equivalent NumPy function:

>>> np.bitwise_not(arr)array([False,  True, False,  True])

You cannot use the not operator or the operator.not function on NumPy arrays because these require that these return a single bool (not an array of booleans), however NumPy also contains a logical not function that works element-wise:

>>> np.logical_not(arr)array([False,  True, False,  True])

That can also be applied to non-boolean arrays:

>>> arr = np.array([0, 1, 2, 0])>>> np.logical_not(arr)array([ True, False, False,  True])

Customizing your own classes

not works by calling bool on the value and negate the result. In the simplest case the truth value will just call __bool__ on the object.

So by implementing __bool__ (or __nonzero__ in Python 2) you can customize the truth value and thus the result of not:

class Test(object):    def __init__(self, value):        self._value = value    def __bool__(self):        print('__bool__ called on {!r}'.format(self))        return bool(self._value)    __nonzero__ = __bool__  # Python 2 compatibility    def __repr__(self):        return '{self.__class__.__name__}({self._value!r})'.format(self=self)

I added a print statement so you can verify that it really calls the method:

>>> a = Test(10)>>> not a__bool__ called on Test(10)False

Likewise you could implement the __invert__ method to implement the behavior when ~ is applied:

class Test(object):    def __init__(self, value):        self._value = value    def __invert__(self):        print('__invert__ called on {!r}'.format(self))        return not self._value    def __repr__(self):        return '{self.__class__.__name__}({self._value!r})'.format(self=self)

Again with a print call to see that it is actually called:

>>> a = Test(True)>>> ~a__invert__ called on Test(True)False>>> a = Test(False)>>> ~a__invert__ called on Test(False)True

However implementing __invert__ like that could be confusing because it's behavior is different from "normal" Python behavior. If you ever do that clearly document it and make sure that it has a pretty good (and common) use-case.


Python has a "not" operator, right? Is it not just "not"? As in,

  return not bool