布尔运算符与按位运算符


75

我对何时应该使用布尔运算符与按位运算符感到困惑

  • and&
  • or|

有人能启发我何时使用每种药物,何时使用一种药物会影响我的结果?


14
请注意,您将获得的答案也大致适用于所有其他(主流命令性)语言。

Answers:


77

以下是一些准则:

  • 布尔运算符通常用于布尔值,而按位运算符通常用于数值。
  • 布尔运算符是短路,但按位运算符不是短路。

短路行为在这样的表达式中很有用:

if x is not None and x.foo == 42:
    # ...

按位运算&符无法正常工作,因为总是会评估双方,即AttributeError: 'NoneType' object has no attribute 'foo'。当您使用布尔and运算符时,如果第一个为False,则不计算第二个表达式。同样or,如果第一个参数为True,则不评估第二个参数。


13
补充:在Python&|,,^也设置操作。
kennytm 2010年

5
附加补充说明:在Python中,按位不允许混合类型,但布尔允许。例如True or "True",很好(它将返回第一个真实值),但是True | "True"将引发异常。
汉妮(Hannele)'16

8
@Hannele与混合类型无关。按位运算仅对整数有意义,任何其他类型都将引发异常。这里的要点是,Python将False和True分别视为0和1:0 == False1 == True都为true。
努诺·安德烈

1
@NunoAndré确实,这是一个更准确的解释。谢谢!
汉内利

24

从理论上讲,andor直接来自布尔逻辑(因此对两个布尔进行运算以产生布尔),&而且|将布尔和/或应用于整数的各个位。这里有很多关于后者如何精确工作的问题。

以下是可能会影响您结果的实际差异:

  1. andor短路,例如True or sys.exit(1)将不退出,因为对于第一操作数(的一定值True or ...False and ...),第二个是不会改变的结果,从而不需要进行评价。不过|&不短路-True | sys.exit(1)抛出你离开的REPL。
  2. &|是常规运算符,可以重载,而andor则伪造成该语言(尽管强制转换为布尔值的特殊方法可能会有副作用)。
    • 这也适用于其他一些带有运算符重载的语言
  3. andor返回操作数的值,而不是Trueor False。这不会改变在条件布尔表达式的含义- 1 or True1的,但1也是正确的。但是它曾经被用来模拟条件运算符(cond ? true_val : false_val在C语法中,true_val if cond else false_val在Python中)。对于&|,结果类型取决于操作数如何重载相应的特殊方法(True & Falseis False99 & 7is 3,set的并集/交集...)。
    • 这也适用于其他一些语言,例如Ruby,Perl和Javascript

但是即使即使例如a_boolean & another_boolean将相同地工作,也使用正确的解决方案and-仅仅因为andor与布尔表达式和条件相关联,而&and则|代表位摆动。


21

这是另一个差异,刚才让我感到困惑:因为&(和其他按位运算符)比and(和其他布尔运算符)具有更高的优先级,因此以下表达式得出的值不同:

0 < 1 & 0 < 2

0 < 1 and 0 < 2

换句话讲,第一屈服False等于0 < (1 & 0) < 2,因此0 < 0 < 2,因此0 < 0 and 0 < 2


4

如果您尝试在中执行按元素进行布尔运算numpy,则答案会有所不同。您可以将&|用于逐个元素的布尔运算,但是andor会返回值错误。

为了安全起见,您可以使用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)

3

提示在名称中:

  • 布尔运算符用于执行逻辑运算(编程和形式逻辑中常见的真相测试)
  • 按位运算符用于“位扭曲”(字节和数字数据类型中的位的低级操作)

尽管使用位运算符进行逻辑运算是可能并且确实有时是希望的(通常出于效率原因),但出于此类目的,通常应避免使用它们,以防止出现细微的错误和不良的副作用。

如果需要操纵位,则将专门构建按位运算符。有趣的书:《Hackers Delight》包含了一些酷而真正有用的示例,这些示例可以通过位旋转实现。


2

一般规则是对现有的操作数使用适当的运算符。使用布尔(逻辑)与运营商布尔操作数,按位与(宽)运营商整体的操作数(注:相当于0,和1)。唯一的“棘手”方案是将布尔运算符应用于非布尔操作数。
让我们来看一个简单的示例,如[SO]中所述:Python-'and'和'&'之间的区别
5 & 7 vs 5 and 7 .。

对于按位),事情非常简单:

5     = 0b101
7     = 0b111
-----------------
5 & 7 = 0b101 = 5

对于逻辑,这是[Python.Docs]:布尔运算的状态(重点是我的):

(请注意,都不限制值和类型,它们返回FalseTrue,而是返回最后一个计算的参数

范例

>>> 5 and 7
7
>>> 7 and 5
5

当然,|


1

布尔运算是逻辑运算。

按位运算是对二进制位的运算。

按位运算:

>>> k = 1
>>> z = 3
>>> k & z  
1
>>> k | z  
3

操作:

  • AND &:如果两个位均为1,则为1,否则为0
  • |:如果任一位为1,则为1,否则为0
  • XOR ^:如果位不同,则为1;如果相同,则为0
  • ~':翻转每一位

按位运算的一些用法:

  1. 设置和清除位

布尔运算:

>>> k = True
>>> z = False
>>> k & z  # and
False
>>> k | z  # or
True
>>> 

1
对于布尔运算,不是要用“与”和“或”代替“&”和“ |”吗?
马修·兰金

是的..是的..谢谢,我的意思是那样。
pyfunc

0

布尔值“ 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)

0

逻辑运算

通常用于条件语句。例如:

if a==2 and b>10:
    # Do something ...

这意味着如果两个条件(a==2b>10)同时为真,则可以执行条件语句主体。

按位运算

用于数据处理和提取。例如,如果要提取整数的四个LSB(最低有效位),则可以执行以下操作:

p & 0xF

问题是关于Python的,但似乎这个答案是用另一种语言编写的-也许是Ruby?无论如何,我把它修好了。LMK如果我错过了任何事情。
wjandrea
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.