Python 布尔运算符与位运算符
我不知道什么时候应该使用布尔运算符还是按位运算符Python 布尔运算符与位运算符,python,bitwise-operators,boolean-operations,Python,Bitwise Operators,Boolean Operations,我不知道什么时候应该使用布尔运算符还是按位运算符 和与和 或vs| 有没有人能告诉我什么时候使用它们,什么时候使用它们会影响我的结果 以下是一些指导原则: 布尔运算符通常用于布尔值,但位运算符通常用于整数值 布尔运算符是短路,但位运算符不是短路 短路行为在以下表达式中很有用: if x is not None and x.foo == 42: # ... 这在按位&运算符中无法正常工作,因为始终会对两侧进行求值,并给出AttributeError:“NoneType”对象没有属
与和
和
vs或
|
有没有人能告诉我什么时候使用它们,什么时候使用它们会影响我的结果 以下是一些指导原则:
- 布尔运算符通常用于布尔值,但位运算符通常用于整数值
- 布尔运算符是短路,但位运算符不是短路
if x is not None and x.foo == 42:
# ...
这在按位
&
运算符中无法正常工作,因为始终会对两侧进行求值,并给出AttributeError:“NoneType”对象没有属性“foo”
。使用布尔和运算符时,如果第一个表达式为False,则不会计算第二个表达式。类似地,如果第一个参数为真,或
不计算第二个参数。布尔运算是逻辑运算
按位操作是对二进制位的操作
按位操作:
>>> k = 1
>>> z = 3
>>> k & z
1
>>> k | z
3
>>> k = True
>>> z = False
>>> k & z # and
False
>>> k | z # or
True
>>>
行动:
>>> k = 1
>>> z = 3
>>> k & z
1
>>> k | z
3
>>> k = True
>>> z = False
>>> k & z # and
False
>>> k | z # or
True
>>>
- 和
&
:如果两个位都是1,则为1,否则为0
- 或
|
:如果任一位为1,则为1,否则为0
- 异或
^
:如果位不同,则为1;如果位相同,则为0
- 非
~
':翻转每个位
按位操作的一些用途:
>>> k = 1
>>> z = 3
>>> k & z
1
>>> k | z
3
>>> k = True
>>> z = False
>>> k & z # and
False
>>> k | z # or
True
>>>
设置和清除位
布尔运算:
>>> k = 1
>>> z = 3
>>> k & z
1
>>> k | z
3
>>> k = True
>>> z = False
>>> k & z # and
False
>>> k | z # or
True
>>>
提示出现在名称中:
- 布尔运算符用于执行逻辑运算(真值测试在编程和形式逻辑中很常见)
- 按位运算符用于“位旋转”(字节和数字数据类型中位的低级操作)
虽然使用位运算符执行逻辑操作是可能的,而且有时确实是可取的(通常是出于效率原因),但通常应避免使用位运算符,以防止出现细微的错误和不必要的副作用
如果需要操作位,则按位运算符是专门构建的。这本有趣的书:包含了一些很酷的、真正有用的例子,说明了通过比特旋转可以实现什么。理论上,和和或直接来自布尔逻辑(因此对两个布尔运算产生一个布尔),而&
和|
则将布尔值和/或应用于整数的各个位。关于后者到底是如何工作的,这里有很多问题
以下是可能影响结果的实际差异:
和
和或
短路,例如True或sys.exit(1)
不会退出,因为对于第一个操作数的某个值(True或…
,False和…
),第二个操作数不会改变结果,因此不需要求值。但是
和&
不要短路-True |系统退出(1)
会将您抛出应答器
&
和|
是常规运算符,可以重载,而和
和或
被伪造成语言(尽管强制为布尔值的特殊方法可能有副作用)。
- 这也适用于一些具有运算符重载的其他语言
和
和或
返回操作数的值,而不是True
或False
。这不会改变条件中布尔表达式的含义-1或True
是1
,但1
也是True。但它曾经被用来模拟条件运算符(C语法中为cond?true\u val:false\u val
,Python中为true\u val if cond else false\u val
)。对于&
和|
,结果类型取决于操作数如何重载相应的特殊方法(真与假为假,99&7
为3
,对于集合,其并集/交集…)。
- 这也适用于其他一些语言,如Ruby、Perl和Javascript
但是,即使当一个布尔值和另一个布尔值相同时,正确的解决方案是使用和——这仅仅是因为和和和或与布尔表达式和条件相关,而和和
代表位旋转。这里还有一个区别,这让我困惑了一段时间:因为&
(和其他按位运算符)的优先级高于和(和其他布尔运算符),所以下面的表达式计算为不同的值:
0 < 1 & 0 < 2
0<1&0<2
对
0 < 1 and 0 < 2
0<1和0<2
也就是说,第一种方法产生了False
,因为它相当于0<(1&0)<2
,因此0<0<2
,因此0<0和0<2
,如果您试图在numpy
中执行元素级布尔运算,答案会有所不同。您可以使用&
和|
进行元素布尔运算,但和和或将返回值错误
为了安全起见,您可以使用
Boolean'和'vs.Bitwise'&':
伪代码/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)
一般规则是对现有操作数使用适当的运算符。将布尔(逻辑)运算符与布尔操作数一起使用,将按位运算符与(更宽的)整数操作数一起使用(注:False等于0,True等于1)。唯一“棘手”的场景是将布尔运算符应用于非布尔操作数<让我们举一个简单的例子,如de