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