如何在 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
?
【问题讨论】:
这可能只是伪代码,但int
和bool
都是内置名称(对于它们所代表的类型),不应用作变量名称。
是的,它只是一个伪代码,仅用于演示目的......
if x == True:
应该写成if x:
。
【参考方案1】:
你可以使用:
return not bool
【讨论】:
另外,int in range (....)
效率低下。它将创建一个列表,然后执行线性搜索。比x in range(low, high)
更好的是low <= x < high
。
请注意,not None
将返回 False。至少对我来说,这不是我所期望的。我希望not None
是None
,所以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
如果您想使用需要谓词函数或回调的函数,这些会很有用。
例如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 行为。如果你曾经这样做清楚地记录它并确保它有一个非常好的(和常见的)用例。
【讨论】:
这就是我所说的“完美答案”。谢谢你。你拯救了我的一天!【参考方案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 中获得布尔值的相反(否定)?的主要内容,如果未能解决你的问题,请参考以下文章