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?

45
demandé sur jtbandes 2011-08-11 22:15:35

5 réponses

Vous pouvez simplement utiliser:

return not bool
90
répondu jtbandes 2011-08-11 18:56:53

Python a un opérateur "not", Non? N'est-il pas juste "pas"? Comme dans,

  return not bool
9
répondu Patrick87 2011-08-11 18:17:41

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.

, Par exemple 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]

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).

4
répondu MSeifert 2018-07-01 12:38:08

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é.

1
répondu user1767754 2018-05-30 17:56:13

Vous pouvez simplement comparer le tableau booléen. Par exemple

X = [True, False, True]

Puis

Y = X == False

Vous donnerait

Y = [False, True, False]
-1
répondu Sebastian 2017-10-01 12:18:37