Probablemente la mejor forma sea utilizando el operador not:
>>> value = True
>>> not value
False
>>> value = False
>>> not value
True
Entonces, en lugar de tu código:
if bool == True:
return False
else:
return True
Podrías usar:
return not bool
La negación lógica como función
También hay dos funciones en el operatormódulo operator.not_y su alias operator.__not__en caso de que lo necesite como función en lugar de como operador:
>>> import operator
>>> operator.not_(False)
True
>>> operator.not_(True)
False
Estos pueden ser útiles si desea utilizar una función que requiere una función de predicado o una devolución de llamada.
Por ejemplo mapo 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]
Por supuesto, también se podría lograr lo mismo con una lambdafunción equivalente :
>>> my_not_function = lambda item: not item
>>> list(map(my_not_function, lst))
[False, True, False, True]
No utilice el operador de inversión bit a bit ~en valores booleanos
Uno podría tener la tentación de usar el operador de inversión bit a bit ~o la función de operador equivalente operator.inv(o uno de los otros 3 alias allí). Pero debido a que booles una subclase del intresultado que podría ser inesperado porque no devuelve el "booleano inverso", devuelve el "entero inverso":
>>> ~True
-2
>>> ~False
-1
Eso es porque Truees equivalente a 1y Falsea 0e inversión a nivel de bits opera en la representación bit a bit de los números enteros 1 y 0.
Por tanto, estos no se pueden utilizar para "negar" a bool.
Negación con matrices (y subclases) NumPy
Si está tratando con matrices NumPy (o subclases como pandas.Serieso pandas.DataFrame) que contienen booleanos, en realidad puede usar el operador inverso bit a bit ( ~) para negar todos los booleanos en una matriz:
>>> import numpy as np
>>> arr = np.array([True, False, True, False])
>>> ~arr
array([False, True, False, True])
O la función NumPy equivalente:
>>> np.bitwise_not(arr)
array([False, True, False, True])
No puede usar el notoperador o la operator.notfunción en arreglos NumPy porque estos requieren que estos devuelvan un solo bool(no un arreglo de valores booleanos), sin embargo, NumPy también contiene una función no lógica que funciona por elementos:
>>> np.logical_not(arr)
array([False, True, False, True])
Eso también se puede aplicar a matrices no booleanas:
>>> arr = np.array([0, 1, 2, 0])
>>> np.logical_not(arr)
array([ True, False, False, True])
Personalizando tus propias clases
notfunciona invocando boolel valor y niega el resultado. En el caso más simple, el valor de verdad simplemente llamará __bool__al objeto.
Entonces, al implementar __bool__(o __nonzero__en Python 2) puede personalizar el valor de verdad y, por lo tanto, el resultado de 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__
def __repr__(self):
return '{self.__class__.__name__}({self._value!r})'.format(self=self)
Agregué una printdeclaración para que pueda verificar que realmente llama al método:
>>> a = Test(10)
>>> not a
__bool__ called on Test(10)
False
Del mismo modo, podría implementar el __invert__método para implementar el comportamiento cuando ~se aplica:
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)
Nuevamente con una printllamada para ver que realmente se llama:
>>> a = Test(True)
>>> ~a
__invert__ called on Test(True)
False
>>> a = Test(False)
>>> ~a
__invert__ called on Test(False)
True
Sin embargo, implementarlo __invert__así podría resultar confuso porque su comportamiento es diferente del comportamiento "normal" de Python. Si alguna vez lo hace, documente claramente y asegúrese de que tenga un caso de uso bastante bueno (y común).
intyboolson los dos nombres incorporados (para los tipos que representan), y no se debe utilizar como nombres de variables.