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

Posted

技术标签:

【中文标题】如何在 Python 中获得布尔值的相反(否定)?【英文标题】:How do I get the opposite (negation) of a Boolean in Python? 【发布时间】:2011-10-25 05:47:26 【问题描述】:

对于以下示例:

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

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

【问题讨论】:

这可能只是伪代码,但intbool 都是内置名称(对于它们所代表的类型),不应用作变量名称。 是的,它只是一个伪代码,仅用于演示目的...... if x == True: 应该写成if x: 【参考方案1】:

你可以使用:

return not bool

【讨论】:

另外,int in range (....) 效率低下。它将创建一个列表,然后执行线性搜索。比x in range(low, high) 更好的是low <= x < high 请注意,not None 将返回 False。至少对我来说,这不是我所期望的。我希望not NoneNone,所以not 可以用来否定,即使返回值可能是None。它是在 Python 中实现的,你必须先验证你是否真的得到了一个布尔值。 我想我需要提到@MRAB 提到的int in range(...) 仅在Python 3 之前效率低下,因为除非您运行range(...)list(...) 它正在使用大量( C代码在这里,它基本上是一个自定义的__contains__范围对象:github.com/python/cpython/blob/…【参考方案2】:

Python 有一个“非”运​​算符,对吧?不只是“不”吗?如,

  return not bool

【讨论】:

【参考方案3】:

您可以只比较布尔数组。例如

X = [True, False, True]

然后

Y = X == False

会给你

Y = [False, True, False]

【讨论】:

可能对于 Numpy 数组,但对于标准 Python 列表,这是不正确的。由于 OP 也没有提及,我看不出这是如何回答问题的。【参考方案4】:

如果您尝试实现 toggle,这样每当您重新运行持久代码时,它就会被否定,您可以通过以下方式实现:

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

运行此代码将首先将toggle 设置为True,并且只要调用此sn-p,toggle 就会被取消。

【讨论】:

【参考方案5】:

not operator(逻辑否定)

可能最好的方法是使用运算符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 等价于1False0 并且按位反转对整数 10 的按位表示进行操作。

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

用 NumPy 数组(和子类)求反

如果您正在处理包含布尔值的 NumPy 数组(或 pandas.Seriespandas.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 行为。如果你曾经这样做清楚地记录它并确保它有一个非常好的(和常见的)用例。

【讨论】:

这就是我所说的“完美答案”。谢谢你。你拯救了我的一天!【参考方案6】:

这里接受的答案对于给定场景是最正确的。

这让我对简单地反转一个布尔值感到好奇。事实证明,这里公认的解决方案可以作为一个班轮工作,还有另一个也可以工作。假设你有一个你知道是布尔值的变量“n”,最简单的反转它的方法是:

n = n is False

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

n = not n

后者更清楚,但我想知道性能并通过timeit 进行分析 - 事实证明n = not n 也是反转布尔值的更快方法。

【讨论】:

不要使用n is False进行真实性测试。【参考方案7】:

实现相同结果的另一种方法,我发现这对 pandas 数据框很有用。

如下mousetail的建议:

bool(1 - False)

bool(1 - True)

【讨论】:

熊猫数据帧是否没有逻辑反转,例如 numpy 数组?【参考方案8】:

我认为最紧凑的版本是

self.foobar ^= True

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

【讨论】:

【参考方案9】:

Python 有not 运算符来反转布尔值。

示例:

如果您想反转 return 语句中的值,请使用如下代码。

return not bool

如果您想反转 if 条件中的值,请使用如下代码

if not bool:
    return True
else:
    return False

如果您想在将值传递给方法级别时反转该值,请使用如下代码

check(not bool)

如果您希望在赋值时反转值,请使用如下代码。

key = not bool

【讨论】:

以上是关于如何在 Python 中获得布尔值的相反(否定)?的主要内容,如果未能解决你的问题,请参考以下文章

csharp 使用否定运算符返回布尔表达式的相反值。

如何获取同一张表中不同类别的布尔值的比例

在python中获取随机布尔值?

否定一个布尔变量并将其分配给一个新变量[重复]

python json布尔到小写字符串

Python如何在pandas数据框中提取[]括号内的指定字符串并创建一个具有布尔值的新列