我对何时应该使用布尔运算符与按位运算符感到困惑
and
与&
or
与|
有人能启发我何时使用每种药物,何时使用一种药物会影响我的结果?
Answers:
以下是一些准则:
短路行为在这样的表达式中很有用:
if x is not None and x.foo == 42:
# ...
按位运算&
符无法正常工作,因为总是会评估双方,即AttributeError: 'NoneType' object has no attribute 'foo'
。当您使用布尔and
运算符时,如果第一个为False,则不计算第二个表达式。同样or
,如果第一个参数为True,则不评估第二个参数。
&
中|
,,^
也设置操作。
True or "True"
,很好(它将返回第一个真实值),但是True | "True"
将引发异常。
0 == False
和1 == True
都为true。
从理论上讲,and
它or
直接来自布尔逻辑(因此对两个布尔进行运算以产生布尔),&
而且|
将布尔和/或应用于整数的各个位。这里有很多关于后者如何精确工作的问题。
以下是可能会影响您结果的实际差异:
and
和or
短路,例如True or sys.exit(1)
将不退出,因为对于第一操作数(的一定值True or ...
,False and ...
),第二个是不会改变的结果,从而不需要进行评价。不过|
和&
不短路-True | sys.exit(1)
抛出你离开的REPL。&
和|
是常规运算符,可以重载,而and
和or
则伪造成该语言(尽管强制转换为布尔值的特殊方法可能会有副作用)。
and
并or
返回操作数的值,而不是True
or False
。这不会改变在条件布尔表达式的含义- 1 or True
是1
的,但1
也是正确的。但是它曾经被用来模拟条件运算符(cond ? true_val : false_val
在C语法中,true_val if cond else false_val
在Python中)。对于&
和|
,结果类型取决于操作数如何重载相应的特殊方法(True & False
is False
,99 & 7
is 3
,set的并集/交集...)。
但是即使即使例如a_boolean & another_boolean
将相同地工作,也使用正确的解决方案and
-仅仅因为and
和or
与布尔表达式和条件相关联,而&
and则|
代表位摆动。
如果您尝试在中执行按元素进行布尔运算numpy
,则答案会有所不同。您可以将&
和|
用于逐个元素的布尔运算,但是and
和or
会返回值错误。
为了安全起见,您可以使用numpy逻辑函数。
np.array([True, False, True]) | np.array([True, False, False])
# array([ True, False, True], dtype=bool)
np.array([True, False, True]) or np.array([True, False, False])
# ValueError: The truth value of an array with more than one element is ambiguous. Use a.any() or a.all()
np.logical_or(np.array([True, False, True]), np.array([True, False, False]))
# array([ True, False, True], dtype=bool)
提示在名称中:
尽管使用位运算符进行逻辑运算是可能并且确实有时是希望的(通常出于效率原因),但出于此类目的,通常应避免使用它们,以防止出现细微的错误和不良的副作用。
如果需要操纵位,则将专门构建按位运算符。有趣的书:《Hackers Delight》包含了一些酷而真正有用的示例,这些示例可以通过位旋转实现。
一般规则是对现有的操作数使用适当的运算符。使用布尔(逻辑)与运营商布尔操作数,按位与(宽)运营商整体的操作数(注:假相当于0,和真到1)。唯一的“棘手”方案是将布尔运算符应用于非布尔操作数。
让我们来看一个简单的示例,如[SO]中所述:Python-'and'和'&'之间的区别:5 & 7
vs 5 and 7
.。
对于按位和(&),事情非常简单:
5 = 0b101
7 = 0b111
-----------------
5 & 7 = 0b101 = 5
对于逻辑和,这是[Python.Docs]:布尔运算的状态(重点是我的):
范例:
>>> 5 and 7
7
>>> 7 and 5
5
当然,| 与 或。
布尔运算是逻辑运算。
按位运算是对二进制位的运算。
按位运算:
>>> k = 1
>>> z = 3
>>> k & z
1
>>> k | z
3
操作:
&
:如果两个位均为1,则为1,否则为0|
:如果任一位为1,则为1,否则为0^
:如果位不同,则为1;如果相同,则为0~
':翻转每一位按位运算的一些用法:
布尔运算:
>>> k = True
>>> z = False
>>> k & z # and
False
>>> k | z # or
True
>>>
布尔值“ and”与按位“&”:
伪代码/ Python帮助我理解了两者之间的区别:
def boolAnd(A, B):
# boolean 'and' returns either A or B
if A == False:
return A
else:
return B
def bitwiseAnd(A , B):
# binary representation (e.g. 9 is '1001', 1 is '0001', etc.)
binA = binary(A)
binB = binary(B)
# perform boolean 'and' on each pair of binaries in (A, B)
# then return the result:
# equivalent to: return ''.join([x*y for (x,y) in zip(binA, binB)])
# assuming binA and binB are the same length
result = []
for i in range(len(binA)):
compar = boolAnd(binA[i], binB[i])
result.append(compar)
# we want to return a string of 1s and 0s, not a list
return ''.join(result)