我很困惑何时应该使用布尔与按位运算符
and vs &, or vs |
有人可以告诉我何时使用每个以及何时使用其中一个影响我的结果?
答案 0 :(得分:56)
以下是一些指导原则:
短路行为在这样的表达式中很有用:
if x is not None and x.foo == 42:
# ...
这对于按位&
运算符无法正常工作,因为将始终对双方进行求值,得到AttributeError: 'NoneType' object has no attribute 'foo'
。当您使用布尔and
运算符时,第一个表达式在第一个为False时不会被计算。同样,or
如果第一个参数为True,则不会计算第二个参数。
答案 1 :(得分:18)
理论上,and
和or
直接来自布尔逻辑(因此操作两个布尔值以产生布尔值),而&
和|
应用布尔值和/或整数的各个位。关于后者如何正常工作,这里有很多问题。
以下是可能会影响您结果的实际差异:
and
和or
短路,即True or sys.exit(1)
将不会退出,因为对于第一个操作数的某个值(True or ...
,False and ...
) ,第二个不会改变结果=不需要评估。但是|
和&
没有短路 - True | sys.exit(1)
会让你超出REPL。&
和|
是常规运算符,可能会重载 - and
和or
是伪造的进入语言(尽管至少在Python中,强制到布尔值的特殊方法可能有副作用)。and
和or
返回(总是?从来没有真正理解这一点,我也不需要它)操作数的值而不是True
或False
。这不会改变条件中布尔表达式的含义 - 1 or True
是1
,但1
也是如此。但它曾经被用来模拟一个条件运算符(C语法为cond ? true_val : false_val
,几年后在Python中为true_val if cond else false_val
。对于&
和|
,结果类型取决于操作数如何重载相应的特殊方法(True & False
为False
,99 & 7
为3
,对于集合它的工会/交集......)。但即使是a_boolean & another_boolean
的工作方式相同,正确的解决方案是使用and
- 只是因为and
和or
与布局表达式和条件相关联&
和{{1代表一点点。
答案 2 :(得分:14)
这是一个进一步的区别,刚才让我困惑了一段时间:因为&
(和其他位运算符)的优先级高于and
(以及其他布尔运算符),以下表达式求值不同的价值观:
0 < 1 & 0 < 2
与
0 < 1 and 0 < 2
即,第一个产生False
,因为它相当于0 < (1 & 0) < 2
,因此0 < 0 < 2
,因此0 < 0 and 0 < 2
。
答案 3 :(得分:4)
如果你试图在numpy
中进行逐元素布尔运算,答案会有所不同。您可以使用&
和|
进行逐元素布尔运算,但and
和or
将返回值错误。
为安全起见,您可以使用numpy logic functions。
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)
答案 4 :(得分:2)
布尔运算是逻辑运算。
按位运算是对二进制位的操作。
按位操作:
>>> k = 1
>>> z = 3
>>> k & z
1
>>> k | z
3
操作:
And & 1 if both bits are 1, 0 otherwise
Or | 1 if either bit is 1
Xor ^ 1 if the bits are different, 0 if they're the same
Not ~ Flip each bit
按位运算的一些用法:
1)设置和清除位
布尔运算:
>>> k = True
>>> z = False
>>> k & z # and
False
>>> k | z # or
True
>>>
答案 5 :(得分:2)
提示名称为:
虽然有可能并且实际上有时候(通常出于效率原因)需要使用按位运算符执行逻辑运算,但为了防止出现细微错误和不必要的副作用,通常应该避免使用它们。
如果需要操作位,则按位运算符是专门构建的。这本有趣的书:Hackers Delight包含一些很酷且真正有用的例子,说明了如何通过比特来实现。
答案 6 :(得分:1)
一般规则是对现有操作数使用适当的运算符。使用带布尔操作数的布尔(逻辑)运算符和带(更宽)积分操作数的位运算符(注意: False 等效于 0 , True 到 1 )。唯一“棘手”的情况是将布尔运算符应用于非布尔操作数。
我们举一个简单的例子,如[SO]: Python - Differences between 'and' and '&' [duplicate]:5 & 7
vs。 5 and 7
中所述。
对于按位和 (&amp; ),事情非常简单:
5 = 0b101 7 = 0b111 ----------------- 5 & 7 = 0b101 = 5
对于逻辑和 ,这里有[Python 3]: Boolean operations个州(强调是我的):
示例强>:
>>> 5 and 7 7 >>> 7 and 5 5
当然,这同样适用于 | vs。 或。
答案 7 :(得分:0)
布尔'和'与按位'&amp;':
伪代码/ 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)
答案 8 :(得分:0)
逻辑运算
通常用于条件语句。例如:
if a==2 and b >10 then
/*Do something...*/
endif
这意味着如果两个条件((a == 2)(b> 10))同时为真,则可以执行条件语句主体。
按位操作
按位运算可用于数据处理和提取。例如,如果要提取一个整数的四个LSB(最低有效位),则可以执行以下操作:
提取:
poo & 0x000F
掩盖:
poo | 0xFFF0