2010-10-02 170 views
49

我很困惑,当我应该使用布尔VS位运算符布尔运算VS位运算符

and vs &, or vs | 

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

+13

注意,聪明的你会大致适用于所有其他(主流命令式)语言。 – delnan 2010-10-02 08:54:30

回答

45

这里有几个原则:

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

短路行为是类似于下面的表达式有用:

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

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

+8

补充:在Python中&','|','^'也被设置了操作。 – kennytm 2010-10-02 09:14:10

+2

附加补充:在Python中,按位不允许混合类型,但布尔值将会。例如“True”或“True”是好的(它会返回第一个真值),但是“True |” “真”会抛出异常。 – Hannele 2016-02-10 19:11:11

+4

@Hannele这与混合类型无关。按位操作只对整数有意义,任何其他类型都会抛出异常。这里的要点是,Python将False和True分别视为0和1:'0 == False'和'1 == True'都是真实的。 – 2016-07-30 17:53:51

1

布尔运算是逻辑运算。

按位操作是对二进制位的操作。

位运算:

>>> 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 
>>> 
+0

对于你布尔运算,你不是指“和”和“或”而不是“&”和“|”? – 2010-10-02 09:05:58

+0

是的..是的..谢谢,我的意思是。 – pyfunc 2010-10-02 09:07:27

2

该提示是在名称:

  • 布尔操作符是用于执行逻辑运算(真理在编程和形式逻辑测试常见)
  • 位运算符是用于“位摆弄”(对字节和数字数据类型的位进行低级别操作)

虽然有可能并且有时确实需要(典型的出于效率原因)为了执行按位运算符的逻辑运算,通常应避免出于这种目的,以防止细微的错误和不需要的副作用。

如果您需要操纵位,则按位操作符是专门构建的。有趣的书:Hackers Delight包含了一些很酷且真正有用的例子,它们可以通过点拨来实现。

17

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

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

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

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

+0

Point#3也适用于Ruby,Perl和Javascript。这不是Python特有的。 – kennytm 2010-10-02 09:22:56

11

这里有一个进一步的差异,这让我困惑了一会儿刚才:因为&(等位运算符)具有更高的优先级比and(和其他布尔运算符)下面的表达式求值不同:

0 < 1 & 0 < 2 

0 < 1 and 0 < 2 

要机智,第一收率False因为它等同于0 < (1 & 0) < 2,因此0 < 0 < 2,因此0 < 0 and 0 < 2

3

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

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

布尔 '和' 与位元 '&':

伪代码/ 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)