可能最好的方法是使用运算符not:
>>> value = True
>>> not value
False
>>> value = False
>>> not value
True
所以代替你的代码:
if bool == True:
return False
else:
return True
你可以使用:
return not bool
作为函数的逻辑否定
operator 模块中还有两个函数 operator.not_ 和别名 operator.__not__ 以防您需要它作为函数而不是运算符:
>>> import operator
>>> operator.not_(False)
True
>>> operator.not_(True)
False
如果您想使用需要谓词函数或回调的函数,这些会很有用。
例如map 或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]
当然也可以使用等效的lambda 函数来实现:
>>> my_not_function = lambda item: not item
>>> list(map(my_not_function, lst))
[False, True, False, True]
不要在布尔值上使用按位反转运算符~
可能会想使用按位反转运算符~ 或等效的运算符函数operator.inv(或其他3 个别名之一)。但是因为bool 是int 的子类,所以结果可能出乎意料,因为它不返回“反布尔值”,而是返回“反整数”:
>>> ~True
-2
>>> ~False
-1
这是因为True 等价于1 和False 到0 并且按位反转对整数 1 和0 的按位表示进行操作。
所以这些不能用来“否定”bool。
用 NumPy 数组(和子类)求反
如果您正在处理包含布尔值的 NumPy 数组(或 pandas.Series 或 pandas.DataFrame 等子类),您实际上可以使用按位逆运算符 (~) 来否定 all 布尔值一个数组:
>>> import numpy as np
>>> arr = np.array([True, False, True, False])
>>> ~arr
array([False, True, False, True])
或等效的 NumPy 函数:
>>> np.bitwise_not(arr)
array([False, True, False, True])
您不能在 NumPy 数组上使用 not 运算符或 operator.not 函数,因为它们要求这些返回单个 bool(不是布尔数组),但是 NumPy 还包含一个逻辑非函数-明智的:
>>> np.logical_not(arr)
array([False, True, False, True])
这也可以应用于非布尔数组:
>>> arr = np.array([0, 1, 2, 0])
>>> np.logical_not(arr)
array([ True, False, False, True])
自定义您自己的类
not 通过在值上调用bool 并否定结果来工作。在最简单的情况下,truth value 只会在对象上调用__bool__。
因此,通过实现__bool__(或Python 2 中的__nonzero__),您可以自定义真值以及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)
我添加了一个print 语句,以便您可以验证它确实调用了该方法:
>>> a = Test(10)
>>> not a
__bool__ called on Test(10)
False
同样,您可以实现__invert__ 方法来实现应用~ 时的行为:
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)
再次调用print 以查看它是否实际被调用:
>>> a = Test(True)
>>> ~a
__invert__ called on Test(True)
False
>>> a = Test(False)
>>> ~a
__invert__ called on Test(False)
True
但是,像这样实现__invert__ 可能会令人困惑,因为它的行为不同于“正常”的 Python 行为。如果你曾经这样做清楚地记录它并确保它有一个非常好的(和常见的)用例。