布尔运算符与按位运算符

Jie*_*eng 62 python bitwise-operators boolean-operations

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

__PRE__

可能有人开导我,当我用每时都会使用一个比其他影响我的结果吗?

Mar*_*ers 63

以下是一些指导原则:

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

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

if x is not None and x.foo == 42:
    # ...
Run Code Online (Sandbox Code Playgroud)

对于按位运算&符,这将无法正常工作,因为将始终对双方进行求值AttributeError: 'NoneType' object has no attribute 'foo'.当您使用布尔and运算符时,当第一个表达式为False时,不会计算第二个表达式.or如果第一个参数为True,同样不会评估第二个参数.

  • 补充:在Python`&`,`|`中,`^`也是设置操作. (11认同)
  • @Hannele这与混合类型无关.按位运算只对整数有意义,任何其他类型都会引发异常.这里的要点是Python将False和True分别视为0和1:"0 == False"和"1 == True"都是真的. (5认同)
  • 附加补充:在Python中,逐位不允许混合类型,但布尔将.例如`True或"True"`很好(它会返回第一个真值),但是`True | "真"`会抛出异常. (4认同)

小智 20

从理论上讲,andor直来自布尔逻辑(并且因此在两个布尔操作以产生一个布尔),而&|布尔应用和/或整数的各个位.关于后者如何正确运作,这里有很多问题.

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

  1. andor短路,即,True or sys.exit(1)将不会退出,因为对于一定的值(True or ...,False and ...第一操作数的),第二个不会改变结果=并不需要进行评估.不过|&不短路- True | sys.exit(1)抛出你离开的REPL.
  2. (仅适用于某些带有运算符重载的语言,包括Python :) &并且|是常规运算符并且可以重载 - and并且or伪造成语言(尽管至少在Python中,强制到布尔值的特殊方法可能有副作用).
  3. (仅适用于几种语言[参见KennyTM的评论] :) andor返回(总是?从来没有真正理解这一点,我也不需要它)操作数的值而不是TrueFalse.这不会改变条件中布尔表达式的含义 - 1 or True1,但1也是如此.但它曾经被用来模拟一个条件运算符(cond ? true_val : false_val在C语法中,true_val if cond else false_val几年后在Python中).对于&|,结果类型取决于操作数如何重载相应的特殊方法(True & FalseFalse,99 & 73,对于它的联合/交集......).

但是,即使eg a_boolean & another_boolean会以相同的方式工作,正确的解决方案正在使用and- 只是因为and并且or与布尔表达式和条件相关联,&而且|代表比特笨拙.


Are*_*end 17

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

0 < 1 & 0 < 2
Run Code Online (Sandbox Code Playgroud)

0 < 1 and 0 < 2
Run Code Online (Sandbox Code Playgroud)

机智,第一产率False,因为它相当于0 < (1 & 0) < 2,因此0 < 0 < 2,因此0 < 0 and 0 < 2.


C8H*_*4O2 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)
Run Code Online (Sandbox Code Playgroud)