Prawdopodobnie najlepszym sposobem jest użycie operatora not
:
>>> value = True
>>> not value
False
>>> value = False
>>> not value
True
Więc zamiast twojego kodu:
if bool == True:
return False
else:
return True
Możesz użyć:
return not bool
Logiczna negacja jako funkcja
W operator
module są również dwie funkcje operator.not_
i jego alias operator.__not__
na wypadek, gdybyś potrzebował go jako funkcji zamiast operatora:
>>> import operator
>>> operator.not_(False)
True
>>> operator.not_(True)
False
Mogą być przydatne, jeśli chcesz użyć funkcji, która wymaga funkcji predykatu lub wywołania zwrotnego.
Na przykład map
lub 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]
Oczywiście to samo można osiągnąć za pomocą równoważnej lambda
funkcji:
>>> my_not_function = lambda item: not item
>>> list(map(my_not_function, lst))
[False, True, False, True]
Nie używaj odwracającego operatora bitowego ~
na wartościach logicznych
Można pokusić się o użycie bitowego operatora odwracającego ~
lub równoważnej funkcji operatora operator.inv
(lub jednego z pozostałych 3 aliasów). Ale ponieważ bool
jest to podklasa int
wyniku, może być nieoczekiwana, ponieważ nie zwraca „odwrotnej wartości logicznej”, zwraca „odwrotną liczbę całkowitą”:
>>> ~True
-2
>>> ~False
-1
Dzieje się tak, ponieważ True
jest równoważne 1
i False
do, 0
a inwersja bitowa działa na bitowej reprezentacji liczb całkowitych 1
i 0
.
Dlatego nie można ich użyć do „zanegowania” a bool
.
Negacja z tablicami NumPy (i podklasami)
Jeśli masz do czynienia z tablicami NumPy (lub podklasami takimi jak pandas.Series
lub pandas.DataFrame
) zawierającymi wartości logiczne, możesz w rzeczywistości użyć operatora odwrotnego bitowego ( ~
), aby zanegować wszystkie wartości logiczne w tablicy:
>>> import numpy as np
>>> arr = np.array([True, False, True, False])
>>> ~arr
array([False, True, False, True])
Lub równoważna funkcja NumPy:
>>> np.bitwise_not(arr)
array([False, True, False, True])
Nie można używać not
operatora ani operator.not
funkcji w tablicach NumPy, ponieważ wymagają one, aby zwracały one pojedynczy bool
(nie tablicę wartości logicznych), jednak NumPy zawiera również funkcję logiczną, która nie działa z uwzględnieniem elementów:
>>> np.logical_not(arr)
array([False, True, False, True])
Można to również zastosować do tablic innych niż boolowskie:
>>> arr = np.array([0, 1, 2, 0])
>>> np.logical_not(arr)
array([ True, False, False, True])
Dostosowywanie własnych zajęć
not
działa poprzez wywołanie bool
wartości i zanegowanie wyniku. W najprostszym przypadku wartość prawda po prostu wywoła __bool__
obiekt.
Tak więc implementując __bool__
(lub __nonzero__
w Pythonie 2) możesz dostosować wartość prawdy, a tym samym wynik 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__
def __repr__(self):
return '{self.__class__.__name__}({self._value!r})'.format(self=self)
Dodałem print
oświadczenie, abyś mógł sprawdzić, czy naprawdę wywołuje metodę:
>>> a = Test(10)
>>> not a
__bool__ called on Test(10)
False
Podobnie możesz zaimplementować __invert__
metodę, aby zaimplementować zachowanie, gdy ~
jest stosowane:
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)
Znowu z print
wezwaniem, aby zobaczyć, że faktycznie się nazywa:
>>> a = Test(True)
>>> ~a
__invert__ called on Test(True)
False
>>> a = Test(False)
>>> ~a
__invert__ called on Test(False)
True
Jednak implementacja __invert__
tego typu może być myląca, ponieważ jej zachowanie różni się od „normalnego” zachowania w Pythonie. Jeśli kiedykolwiek to zrobisz, udokumentuj to i upewnij się, że ma całkiem dobry (i powszechny) przypadek użycia.
int
ibool
są obie nazwy wbudowane (dla typów, które reprezentują) i nie powinny być wykorzystywane jako nazw zmiennych.