对于以下示例:
def fuctionName(int, bool):
if int in range(...):
if bool == True:
return False
else:
return True
有没有办法跳过第二个 if 语句?只是告诉计算机返回布尔值 bool
的相反值吗?
要否定一个布尔值,你可以使用 not
运算符:
not bool
在你的情况下,可以将if
/return
代码块替换为:
return not bool
请务必注意运算符优先级规则,以及取反的is
和in
运算符:a is not b
和a not in b
。
int in range (....)
这种写法效率不高,它会创建一个列表,然后进行线性搜索。比起x in range(low, high)
,更好的写法是low <= x < high
。 - MRABnot None
将返回 False。至少对我来说,这不是我所期望的。我希望 not None
是 None
,这样即使返回值可能是 None
,也可以使用 not
进行否定。在 Python 中实现的方式是,您必须先验证您实际上获得了一个布尔值。 - omniint in range(...)
只在Python 3之前是低效的,因为除非你通过list(...)
运行range(...)
,否则它使用了一种极其高效的方式(<-我的理解)。不过,我还没有检查过那部分的C代码,所以我不知道他们是如何做到的。 - rautamiekka__contains__
:https://github.com/python/cpython/blob/a330365ca5ae836075f306334ab648bf23471481/Objects/rangeobject.c#L430-L431 - jtbandes最好的方法可能就是使用 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
如果您想使用需要谓词函数或回调函数的函数,则可以使用它们。
>>> 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数组(或子类,如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也包含按元素计算的逻辑非函数:
>>> 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
语句,以便您可以验证它是否真的调用了该方法:
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行为不同。如果您确实这样做,请清楚地记录下来,并确保它具有相当好(和常见的)用例。
Python有一个“not”运算符,对吗?它不仅仅是“not”吗?就像这样:
return not bool
在这里接受的答案是针对给定场景最正确的。
不过,它让我想到了一般情况下简单地翻转布尔值。事实证明,在这里接受的解决方案可以作为一行代码解决,还有另一个一行代码的解决方案也可行。假设您有一个名为“n”的变量,您知道它是布尔类型,反转它最简单的方法是:
n = n is False
这是我最初的解决方案,然后是从这个问题中接受的答案:
n = not n
后者更加清晰,但我对性能有疑问,并使用timeit
进行了测试 - 结果表明,在反转布尔值时,n = not n
也是更快的方法。
n is False
进行真值测试。 - gerritX = [True, False, True]
那么
Y = X == False
将为你提供
Y = [False, True, False]
我认为最简洁的版本是
self.foobar ^= True
它不需要重复整个名称,并且适用于纯布尔值。
如果您想实现一个切换开关,以便每次重新运行持久代码时都被否定,您可以按照以下方式实现:
try:
toggle = not toggle
except NameError:
toggle = True
toggle
设置为True
,每当调用此片段时,toggle将被取反。另一种实现相同结果的方法,我发现对于pandas数据帧非常有用。
如下所建议的mousetail:
bool(1 - False)
bool(1 - True)
int
和bool
都是内置名称(表示它们代表的类型),不应作为变量名使用。我会为你翻译这句话,并尽可能使其通俗易懂,但不会改变原意。 - SingleNegationElimination