88

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

  • and对比&
  • or对比|

有人可以告诉我我什么时候使用每一个,什么时候使用一个会影响我的结果?

4

9 回答 9

94

以下是一些指导方针:

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

短路行为在如下表达式中很有用:

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

这不适用于按位运算&符,因为双方总是会被评估,给出AttributeError: 'NoneType' object has no attribute 'foo'. 当您使用布尔and运算符时,当第一个表达式为 False 时,不会计算第二个表达式。如果第一个参数为真,则同样or不计算第二个参数。

于 2010-10-02T08:56:33.363 回答
25

理论上,and直接or来自布尔逻辑(因此对两个布尔值进行运算以产生一个布尔值),同时&|布尔值和/或应用于整数的各个位。这里有很多关于后者如何工作的问题。

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

  1. and并且or短路,例如True or sys.exit(1)不会退出,因为对于第一个操作数(True or ..., False and ...)的某个值,第二个操作数不会改变结果,因此不需要评估。但是不要短路 -|让你脱离 REPL。&True | sys.exit(1)
  2. &and|是常规运算符,可以重载,而andandor被伪造到语言中(尽管强制转换为布尔值的特殊方法可能有副作用)。
    • 这也适用于其他一些具有运算符重载的语言
  3. andor返回操作数的值而不是Trueor False。这不会改变条件中布尔表达式的含义 - 1 or Trueis 1,但1也是如此。但它曾经被用来模拟条件运算符(cond ? true_val : false_val在 C 语法中,true_val if cond else false_val在 Python 中)。对于&and |,结果类型取决于操作数如何重载各自的特殊方法(True & Falseis False99 & 7is 3,对于集合,它是联合/交集......)。
    • 这也适用于其他一些语言,如 Ruby、Perl 和 Javascript

但是,即使 ega_boolean & another_boolean的工作方式相同,正确的解决方案是使用and- 仅仅因为andandor与布尔表达式和条件相关联,而&and|代表位旋转。

于 2010-10-02T09:16:23.333 回答
24

这是一个进一步的区别,刚才让我困惑了一段时间:因为&(和其他位运算符)比(和其他布尔运算符)具有更高的优先级and,所以以下表达式计算为不同的值:

0 < 1 & 0 < 2

相对

0 < 1 and 0 < 2

也就是说,第一个产生False,因为它等价于0 < (1 & 0) < 2,因此0 < 0 < 2,因此0 < 0 and 0 < 2

于 2014-09-20T14:07:03.060 回答
5

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

为了安全起见,您可以使用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)
于 2016-08-03T17:13:36.300 回答
3

提示在名称中:

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

虽然使用按位运算符执行逻辑运算是可能的,而且有时确实是可取的(通常出于效率原因),但您通常应该避免使用它们,以防止细微的错误和不必要的副作用。

如果您需要操作位,则按位运算符是专门构建的。这本有趣的书:Hackers Delight包含了一些很酷且真正有用的示例,说明了通过比特旋转可以实现什么。

于 2010-10-02T09:08:36.510 回答
3

一般规则是对现有操作数使用适当的运算符。将布尔(逻辑)运算符与布尔操作数一起使用,将按位运算符与(更宽的)整数操作数一起使用(注意:False等效于0True等效于1)。唯一“棘手”的场景是将布尔运算符应用于非布尔操作数。
让我们举一个简单的例子,如[SO]: Python - Differences between 'and' and '&' :
5 & 7 vs. 5 and 7中所述。

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

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

对于逻辑and,这里是[Python.Docs]: Boolean operations states (重点是我的):

(请注意,它们返回的值和类型既不也不限制为FalseTrue而是返回最后评估的参数

示例

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

当然,这同样适用于|

于 2018-05-21T10:15:16.680 回答
1

布尔运算是逻辑运算。

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

位运算:

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

操作:

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

位运算的一些用途:

  1. 设置和清除位

布尔运算:

>>> k = True
>>> z = False
>>> k & z  # and
False
>>> k | z  # or
True
>>> 
于 2010-10-02T08:59:14.607 回答
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)
于 2017-09-26T23:21:55.633 回答
0

逻辑运算

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

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

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

位运算

用于数据操作和提取。例如,如果要提取整数的四个 LSB(最低有效位),可以这样做:

p & 0xF
于 2019-07-28T20:52:00.067 回答