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 bool
moet 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 not
te 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 operator
Module 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.
>>> 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 lambda
functie:
>>> 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 bool
een 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 True
gelijk is aan 1
en False
aan 0
en bitsgewijze inversie werkt op de bitsgewijze weergave van de gehele getallen1
en 0
.
Deze kunnen dus niet worden gebruikt om een bool
te “negeren”.
Negatie met NumPy-arrays (en subklassen)
Als je te maken hebt met NumPy-arrays (of subklassen zoals pandas.Series
of 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 not
of de functie operator.not
niet gebruiken op NumPy-arrays omdat deze vereisen dat deze een enkele bool
retourneren (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
not
werkt door bool
op 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 print
aanroep 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 n
is 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 toggle
instellen op True
en 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.