在 Python 中如何得到布尔值的相反(否定) ?

对于以下样本:

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

有办法跳过第二个 if 语句吗?只是告诉计算机返回与布尔值 bool相反的值?

331423 次浏览

要否定一个布尔值,可以使用 not接线员:

not bool

或者,在你的情况下,if/return区块可以替换为:

return not bool

一定要注意 运算符优先规则运算符优先规则,以及否定的 isin操作符: a is not ba not in b

Python 有个“非”操作符,对吧? 不就是“非”吗,

  return not bool

你可以只比较布尔数组

X = [True, False, True]

那么

Y = X == False

会给你

Y = [False, True, False]

如果您试图实现一个 切换,以便在任何时候重新运行一个持久性代码,否定它,您可以实现如下:

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

运行此代码将首先将 toggle设置为 True,并且任何时候调用这个代码片段列表,切换将被否定。

(逻辑非)

也许最好的方法是使用操作员 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

如果您希望使用需要谓词函数或回调函数的函数,这些方法可能非常有用。

例如 mapfilter:

>>> 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个别名中的一个)。但是因为 boolint的一个子类,结果可能出乎意料,因为它不返回“逆布尔值”,而是返回“逆整数”:

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

这是因为 True等价于 1False等价于 0,并且按位反转操作 整数 10的按位表示。

因此,这些不能用来“否定”一个 bool

用 NumPy 数组(和子类)求逆

如果你正在处理包含布尔值的 NumPy 数组(或者像 pandas.Series或者 pandas.DataFrame这样的子类) ,你可以使用位逆运算符(~)来消除数组中的 所有布尔值:

>>> 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 也包含一个逻辑 not 函数,它在元素方面起作用:

>>> 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并取消结果来工作。在最简单的情况下,真相价值将只调用对象上的 __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 行为。如果您曾经清楚地记录它,并确保它有一个非常好的(和常见的)用例。

对于给定的场景,这里公认的答案是最正确的。

这让我不禁想到,一般情况下,只需要简单地反转一个布尔值就可以了。事实证明,这里接受的解决方案作为一行程序工作,还有另一行程序也可以工作。假设你有一个你知道是布尔型的变量“ n”,最简单的方法是:

n = n is False

这是我最初的解决方案,然后是这个问题的公认答案:

n = not n

后者比较清楚,但我想知道性能如何,并通过 timeit进行了修改——结果发现,在 n = not n也是更快地反转布尔值的方法。

另一种方法来实现同样的结果,我发现这对熊猫数据框架很有用。

正如下面由 mousetail 提出的建议:

bool(1 - False)


bool(1 - True)

我认为最紧凑的版本是

Self. foobar ^ = True

它不需要重复整个名称,并且可以使用纯布尔值。