Provavelmente, a melhor maneira é usar o operador not
:
>>> value = True
>>> not value
False
>>> value = False
>>> not value
True
Então, em vez de seu código:
if bool == True:
return False
else:
return True
Você pode usar:
return not bool
A negação lógica como função
Também há duas funções no operator
módulo operator.not_
e seu apelido operator.__not__
caso você precise dele como função em vez de como operador:
>>> import operator
>>> operator.not_(False)
True
>>> operator.not_(True)
False
Isso pode ser útil se você quiser usar uma função que requer uma função de predicado ou um retorno de chamada.
Por exemplo map
ou 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]
Claro que o mesmo também pode ser alcançado com uma lambda
função equivalente :
>>> my_not_function = lambda item: not item
>>> list(map(my_not_function, lst))
[False, True, False, True]
Não use o operador invertido bit a bit ~
em booleanos
Alguém pode ficar tentado a usar o operador invertido bit a bit ~
ou a função de operador equivalente operator.inv
(ou um dos outros 3 aliases lá). Mas porque bool
é uma subclasse do int
resultado pode ser inesperado porque não retorna o "booleano inverso", ele retorna o "inteiro inverso":
>>> ~True
-2
>>> ~False
-1
Isso porque True
é equivalente a 1
e False
to 0
e a inversão bit a bit opera na representação bit a bit dos inteiros 1
e 0
.
Portanto, eles não podem ser usados para "negar" a bool
.
Negação com matrizes NumPy (e subclasses)
Se você estiver lidando com matrizes NumPy (ou subclasses como pandas.Series
ou pandas.DataFrame
) contendo booleanos, você pode usar o operador inverso bit a bit ( ~
) para negar todos os booleanos em uma matriz:
>>> import numpy as np
>>> arr = np.array([True, False, True, False])
>>> ~arr
array([False, True, False, True])
Ou a função NumPy equivalente:
>>> np.bitwise_not(arr)
array([False, True, False, True])
Você não pode usar o not
operador ou a operator.not
função em matrizes NumPy porque eles exigem que retornem um único bool
(não uma matriz de booleanos); no entanto, NumPy também contém uma função não lógica que funciona em elementos:
>>> np.logical_not(arr)
array([False, True, False, True])
Isso também pode ser aplicado a matrizes não booleanas:
>>> arr = np.array([0, 1, 2, 0])
>>> np.logical_not(arr)
array([ True, False, False, True])
Personalizando suas próprias aulas
not
funciona chamando bool
o valor e negando o resultado. No caso mais simples, o valor verdade apenas chamará __bool__
o objeto.
Portanto, ao implementar __bool__
(ou __nonzero__
no Python 2), você pode personalizar o valor verdadeiro e, portanto, o 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)
Eu adicionei uma print
instrução para que você possa verificar se ela realmente chama o método:
>>> a = Test(10)
>>> not a
__bool__ called on Test(10)
False
Da mesma forma, você pode implementar o __invert__
método para implementar o comportamento quando ~
é aplicado:
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)
Novamente com uma print
chamada para ver se é realmente chamado:
>>> a = Test(True)
>>> ~a
__invert__ called on Test(True)
False
>>> a = Test(False)
>>> ~a
__invert__ called on Test(False)
True
No entanto, uma implementação __invert__
como essa pode ser confusa porque seu comportamento é diferente do comportamento "normal" do Python. Se você fizer isso, documente-o claramente e certifique-se de que tenha um caso de uso muito bom (e comum).
int
ebool
são nomes internos (para os tipos que representam) e não devem ser usados como nomes de variáveis.