【问题标题】:How do I get the opposite (negation) of a Boolean in Python?如何在 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:

标签: python boolean


【解决方案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
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2015-06-19
          • 2014-11-07
          • 2020-03-04
          • 2014-04-09
          • 1970-01-01
          • 2019-02-20
          • 1970-01-01
          相关资源
          最近更新 更多