valores - ¿Cómo obtengo lo opuesto(negación) de un booleano en Python?
operadores relacionales en python (5)
El operador not
(negación lógica)
Probablemente la mejor manera es usar 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 operator
operator.not_
operator.__not__
y su operator.__not__
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 usar una función que requiere una función de predicado o una devolución de llamada.
>>> 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, lo mismo podría lograrse con una función lambda
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 booleanos
Uno podría estar tentado de usar el operador de inversión bit a bit ~
o la función de operator.inv
equivalente operator.inv
(o uno de los otros 3 alias allí). Pero como bool
es una subclase de int
el resultado puede ser inesperado porque no devuelve el "booleano inverso", sino que devuelve el "entero inverso":
>>> ~True
-2
>>> ~False
-1
Esto se debe a que True
es equivalente a 1
y False
a 0
y la inversión en modo bit opera en la representación bit a bit de los enteros 1
y 0
.
Entonces estos no pueden ser usados para "negar" un bool
.
Negación con arreglos NumPy (y subclases)
Si está tratando con arreglos NumPy (o subclases como pandas.Series
o pandas.DataFrame
) que contienen booleanos, puede usar el operador bitwise inverso ( ~
) para anular 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 utilizar el operador not
o el operator.not
funcionan en arreglos NumPy porque requieren que estos devuelvan un único bool
(no una matriz de booleanos), sin embargo, NumPy también contiene una función lógica que no funciona en función de los 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
not
funciona al invocar bool
en el valor y negar 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) puedes 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__ # Python 2 compatibility
def __repr__(self):
return ''{self.__class__.__name__}({self._value!r})''.format(self=self)
Agregué una declaración de print
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 método __invert__
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 llamada de print
para ver que en realidad se llama:
>>> a = Test(True)
>>> ~a
__invert__ called on Test(True)
False
>>> a = Test(False)
>>> ~a
__invert__ called on Test(False)
True
Sin embargo, implementar __invert__
esa manera podría ser confuso porque su comportamiento es diferente del comportamiento de Python "normal". Si alguna vez lo hace, documente claramente y asegúrese de que tenga un caso de uso bastante bueno (y común).
Para la siguiente muestra:
def fuctionName(int, bool):
if int in range(...):
if bool == True:
return False
else:
return True
¿Hay alguna manera de omitir la segunda instrucción if? ¿Solo para decirle a la computadora que devuelva lo opuesto a boolean bool
?
Puedes simplemente comparar la matriz booleana. Por ejemplo
X = [True, False, True]
entonces
Y = X == False
te daría
Y = [False, True, False]
Puedes simplemente usar:
return not bool
Python tiene un operador "no", ¿verdad? ¿No es solo "no"? Como en,
return not bool
Si está intentando implementar un alternar , de modo que cada vez que vuelva a ejecutar un código persistente sea negado, puede lograrlo de la siguiente manera:
try:
toggle = not toggle
except NameError:
toggle = True
Al ejecutar este código, primero establecerá el toggle
a True
y cada vez que se llame a este fragmento, se negará el alternar.