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

新手上路,请多包涵

对于以下示例:

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

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

原文由 amyassin 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 969
2 个回答

not 运算符(逻辑非)

可能最好的方法是使用运算符 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 个别名之一)。但是因为 bool 是 --- 的子类 int 结果可能是意外的,因为它不返回“逆布尔值”,它返回“逆整数”:

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

That’s because True is equivalent to 1 and False to 0 and bitwise inversion operates on the bitwise representation of the integers 10

所以这些不能用来“否定” a bool

NumPy 数组(和子类)的否定

如果您正在处理包含布尔值的 NumPy 数组(或子类,如 pandas.Seriespandas.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 ,但是 NumPyan 数组(580 数组)还包含一个按元素工作的逻辑非函数:

 >>> 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 行为。如果你曾经这样做过,请清楚地记录下来并确保它有一个非常好的(和常见的)用例。

原文由 MSeifert 发布,翻译遵循 CC BY-SA 4.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题
logo
Stack Overflow 翻译
子站问答
访问
宣传栏