Hoe krijg ik het tegenovergestelde (negatie) van een Boolean in Python?

Voor het volgende voorbeeld:

def fuctionName(int, bool):
    if int in range(...):
        if bool == True:
            return False
        else:
            return True

Is er een manier om het tweede if-statement over te slaan? Gewoon om de computer te vertellen dat hij het tegenovergestelde van de boolean boolmoet retourneren?


Antwoord 1, autoriteit 100%

Je kunt gewoon gebruiken:

return not bool

Antwoord 2, autoriteit 33%

De not-operator(logische ontkenning)

Waarschijnlijk is de beste manier om de operator notte gebruiken:

>>> value = True
>>> not value
False
>>> value = False
>>> not value
True

Dus in plaats van uw code:

if bool == True:
    return False
else:
    return True

Je zou kunnen gebruiken:

return not bool

De logische ontkenning als functie

Er zijn ook twee functies in de operatorModule operator.not_en Het is alias operator.__not__voor het geval u heb het nodig als functie in plaats van als operator:

>>> import operator
>>> operator.not_(False)
True
>>> operator.not_(True)
False

Deze kunnen handig zijn als u een functie wilt gebruiken die een predicaat-functie of callback vereist.

Bijvoorbeeld mapof 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]

Natuurlijk kan hetzelfde ook worden bereikt met een equivalent lambdafunctie:

>>> my_not_function = lambda item: not item
>>> list(map(my_not_function, lst))
[False, True, False, True]

Gebruik de bitwise-inverturerator niet ~OP BOOOLEANS

Je zou in de verleiding kunnen komen om de bitsgewijze invertoperator ~of de equivalente operatorfunctie operator.inv(of een van de andere 3 aliassen daar). Maar omdat booleen subklasse is van int, kan het resultaat onverwacht zijn omdat het niet de “inverse boolean” retourneert, maar het “inverse integer”:

>>> ~True
-2
>>> ~False
-1

Dat komt omdat Truegelijk is aan 1en Falseaan 0en bitsgewijze inversie werkt op de bitsgewijze weergave van de gehele getallen1en 0.

Deze kunnen dus niet worden gebruikt om een boolte “negeren”.

Negatie met NumPy-arrays (en subklassen)

Als je te maken hebt met NumPy-arrays (of subklassen zoals pandas.Seriesof pandas.DataFrame) die booleans bevatten, kun je de bitsgewijze inverse operator (~) om allebooleans in een array te negeren:

>>> import numpy as np
>>> arr = np.array([True, False, True, False])
>>> ~arr
array([False,  True, False,  True])

Of de equivalente NumPy-functie:

>>> np.bitwise_not(arr)
array([False,  True, False,  True])

U kunt de operator notof de functie operator.notniet gebruiken op NumPy-arrays omdat deze vereisen dat deze een enkele boolretourneren (niet een array van booleans), maar NumPy bevat ook een logische niet-functie die elementsgewijs werkt:

>>> np.logical_not(arr)
array([False,  True, False,  True])

Dat kan ook worden toegepast op niet-booleaanse arrays:

>>> arr = np.array([0, 1, 2, 0])
>>> np.logical_not(arr)
array([ True, False, False,  True])

Je eigen lessen aanpassen

notwerkt door boolop de waarde aan te roepen en het resultaat te negeren. In het eenvoudigste geval zal de waarheidswaardegewoon __bool__op het object.

Dus door __bool__( of __nonzero__in Python 2) je kunt de waarheidswaarde aanpassen en dus het resultaat van 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)

Ik heb een print-statement toegevoegd zodat je kunt controleren of het de methode echt aanroept:

>>> a = Test(10)
>>> not a
__bool__ called on Test(10)
False

Evenzo kunt u de __invert__methode om het gedrag te implementeren wanneer ~wordt toegepast:

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)

Nogmaals met een printaanroep om te zien of het daadwerkelijk heet:

>>> a = Test(True)
>>> ~a
__invert__ called on Test(True)
False
>>> a = Test(False)
>>> ~a
__invert__ called on Test(False)
True

Het op deze manier implementeren van __invert__kan echter verwarrend zijn omdat het gedrag verschilt van het “normale” Python-gedrag. Als je dat ooit doet, documenteer het dan duidelijk en zorg ervoor dat het een redelijk goede (en veelvoorkomende) use-case heeft.


Antwoord 3, autoriteit 5%

Python heeft een “niet”-operator, toch? Is het niet gewoon “niet”? Zoals in,

 return not bool

Antwoord 4, autoriteit 2%

Het geaccepteerde antwoord hier is het meest correct voor het gegeven scenario.

Het maakte me echter af over het eenvoudig om een ​​booleaanse waarde in het algemeen te omzetten. Het blijkt dat de geaccepteerde oplossing hier werkt als één voering, en er is nog een one-liner die ook werkt. Ervan uitgaande dat u een variabele “n” hebt die u weet, is een Boolean, de gemakkelijkste manieren om het te omkeren zijn:

n = n is False

wat mijn originele oplossing was en vervolgens het geaccepteerde antwoord van deze vraag:

n = not n

Dit laatste is duidelijker, maar ik vroeg me af over de prestaties en huilde het via timeit– en het blijkt op n = not nis ook de snellere manier om te omkeren de Booleaanse waarde.


5

U kunt de Boolean-array gewoon vergelijken. Bijvoorbeeld

X = [True, False, True]

Dan

Y = X == False

zou u

geven

Y = [False, True, False]

6

Als u probeert een Toggle te implementeren, zodat u op elk gewenst moment een persistente code opnieuw uitvoert, wordt u dat wordt ontkend, u kunt dat volgen als volgt:

try:
    toggle = not toggle
except NameError:
    toggle = True

Draaiende deze code zal eerst de toggleinstellen op Trueen wanneer deze fragment is genoemd, wordt schakelaar getoond.


7

een andere manier om dezelfde uitkomst te bereiken, die ik nuttig vond voor een Pandas Dataframe.

Zoals hieronder gesuggereerd door Mousetail:

bool(1 - False)
bool(1 - True)

8

Ik denk dat de meest compacte versie

is

self.foobar ^ = true

die niet nodig is om de hele naam te herhalen en werkt met Pure Booleans.

Other episodes