Comment puis-je obtenir le contraire (négation) D'un booléen en Python?
Pour l'échantillon suivant:
def fuctionName(int, bool):
if int in range(...):
if bool == True:
return False
else:
return True
Existe-t-il un moyen d'ignorer la deuxième instruction if? Juste pour dire à l'ordinateur de retourner le contraire du booléen bool
?
5 réponses
Python a un opérateur "not", Non? N'est-il pas juste "pas"? Comme dans,
return not bool
Le not
opérateur (négation logique)
, Probablement, le meilleur moyen est d'utiliser l'opérateur not
:
>>> value = True
>>> not value
False
>>> value = False
>>> not value
True
Donc, au lieu de votre code:
if bool == True:
return False
else:
return True
, Vous pouvez utiliser:
return not bool
La négation logique comme fonction
Il y a aussi deux fonctions dans le operator
module operator.not_
et c'est alias operator.__not__
au cas où vous en auriez besoin comme fonction au lieu de comme opérateur:
>>> import operator
>>> operator.not_(False)
True
>>> operator.not_(True)
False
Ceux-ci peuvent être utiles si vous voulez utilisez une fonction qui nécessite une fonction de prédicat ou un rappel.
>>> 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]
Bien sûr, la même chose pourrait également être réalisée avec une fonction lambda
équivalente:
>>> my_not_function = lambda item: not item
>>> list(map(my_not_function, lst))
[False, True, False, True]
N'utilisez pas l'opérateur d'inversion binaire ~
sur les booléens
On pourrait être tenté d'utiliser l'opérateur d'inversion binaire ~
ou la fonction d'opérateur équivalenteoperator.inv
(ou l'un des 3 autres alias là-bas). Mais parce que bool
est une sous-classe de int
le résultat pourrait être inattendu car il ne renvoie pas le "booléen inverse" , il renvoie le "entier inverse":
>>> ~True
-2
>>> ~False
-1
C'est parce que True
est équivalent à 1
et False
à 0
et l'inversion bit à bit fonctionne sur la représentation bit à BiT des entiers 1
et 0
.
Donc, ceux-ci ne peuvent pas être utilisés pour "nier" un bool
.
Négation avec des tableaux NumPy (et des sous-classes)
Si vous avez affaire à des tableaux NumPy (ou des sous-classes comme pandas.Series
ou pandas.DataFrame
) contenant des booléens vous pouvez réellement utiliser l'opérateur inverse binaire (~
) pour annuler tous les booléens dans un tableau:
>>> import numpy as np
>>> arr = np.array([True, False, True, False])
>>> ~arr
array([False, True, False, True])
Ou la fonction NumPy équivalente:
>>> np.bitwise_not(arr)
array([False, True, False, True])
Vous ne pouvez pas utiliser l'opérateur not
ou la fonction operator.not
sur les tableaux NumPy car ceux-ci nécessitent que ceux-ci renvoient un seul bool
(pas un tableau de booléens), cependant NumPy contient également une fonction not logique qui fonctionne par élément:
>>> np.logical_not(arr)
array([False, True, False, True])
Ça peut également être appliqué aux tableaux Non booléens:
>>> arr = np.array([0, 1, 2, 0])
>>> np.logical_not(arr)
array([ True, False, False, True])
Personnaliser vos propres classes
not
Fonctionne en appelant bool
sur la valeur et annule le résultat. Dans le cas le plus simple, la valeur truth appellera simplement __bool__
sur l'objet.
, Donc par la mise en œuvre de __bool__
(ou __nonzero__
en Python 2) vous pouvez personnaliser la valeur de vérité, et donc le résultat 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)
J'ai ajouté une instruction print
afin que vous puissiez vérifier qu'elle est vraiment appelle la méthode:
>>> a = Test(10)
>>> not a
__bool__ called on Test(10)
False
De même, vous pouvez implémenter le __invert__
méthode pour implémenter le comportement lorsque ~
est appliqué:
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)
Encore une fois avec un appel print
pour voir qu'il est réellement appelé:
>>> a = Test(True)
>>> ~a
__invert__ called on Test(True)
False
>>> a = Test(False)
>>> ~a
__invert__ called on Test(False)
True
Cependant, implémenter __invert__
comme ça pourrait être déroutant car son comportement est différent du comportement Python "normal". Si jamais vous le faites, documentez-le clairement et assurez-vous qu'il a un très bon cas d'utilisation (et commun).
Si vous essayez d'implémenter un toggle , de sorte que chaque fois que vous réexécutez un code persistant, il est Annulé, vous pouvez le réaliser comme suit:
try:
toggle = not toggle
except NameError:
toggle = True
L'exécution de ce code définira d'abord toggle
sur True
et chaque fois que cet extrait est appelé, toggle sera annulé.
Vous pouvez simplement comparer le tableau booléen. Par exemple
X = [True, False, True]
Puis
Y = X == False
Vous donnerait
Y = [False, True, False]