【问题标题】:Using the "not" and "&" operators to check for even number (Python)使用“not”和“&”运算符检查偶数(Python)
【发布时间】:2018-03-09 22:04:05
【问题描述】:

我已经查看了堆栈溢出答案以解决与我的问题类似的问题,但我没有找到可以解决我的问题(herehere)或以一种让我清楚的方式解释的答案。为了理解,我做了如下实验:

def Even1(num): # I understand this and use it
    if num % 2 == 0:
        return num 

def Even2(num):
  return not (num & 1)

def Even3(num):
  return not (num and 1)

 filter(Even1, range(7)) ==> [2, 4, 6]
 filter(Even2, range(7)) ==> [0, 2, 4, 6]
 filter(Even3, range(7)) ==> [0]

1: not (4 & 1) =  True
2: not (1 & 4) =  True
3: not (4 & 2) =  True
4: not (3 & 4) =  True
5: not (4 & 3) =  True
6: not (4 & 4) =  False

7: not (3 & 1) =  False
8: not (1 & 3) =  False
9: not (3 & 2) =  False
10: not (2 & 3) =  False
11: not (3 & 3) =  False

基于#1 到#5,我认为not (x & y) 排列中的任何偶数与任何其他数字的计算结果为 False(由 not 更改为 True)。我认为这与bin(x) 的事实有关,其中x 偶数以0 结尾,而奇数以1 结尾。所以也许not 检查最后一位。但是#6 反驳了这个假设。以及数字的显示顺序 没有影响。

表达式 #6 与表达式 #11 有什么共同点,除了每个表达式都计算相同/相等的数字?

根据 #7 到 #11,它看起来像 not (x & y) 中的奇数,其中 x 和 y 的奇数计算结果为 True(由 not 更改为 False)。那会是正确的吗?

最后,Even2 和 Even3:将 & 替换为 and。我知道第一个是按位的,第二个是逻辑的,但这意味着什么,所以我以结果结束。

【问题讨论】:

    标签: python


    【解决方案1】:

    在 Python 中,1 和 0 的布尔等效项分别为 TrueFalse。尽管 Python 中的任何非零值都被视为 True

    ,但它并没有就此停止

    当您执行even & 1 时,您会得到 0 - 因为任何偶数的最右边位都是 0。当您执行 return not 0 时,从布尔的角度来看,这等效于 return not False,即 return True

    当您执行not (0 and 1) 时,这相当于not (False and True)not False 所以return True

    让我们来看看你的一些测试,看看我们得到了什么:

    not (4 & 1) = not 0100 & 0001 = not 0 = True
    not (1 & 4) = not 0001 & 0100 = not 0 = True
    not (4 & 2) = not 0100 & 0010 = not 0 = True
    not (3 & 4) = not 0011 & 0100 = not 0 = True
    not (4 & 3) = not 0100 & 0011 = not 0 = True
    not (4 & 4) = not 1000 & 1000 = not 4 = False
    
    not (3 & 1) = not 0011 & 0001 = not 1 = False
    not (1 & 3) = not 0001 & 0011 = not 1 = False
    not (2 & 3) = not 0010 & 0011 = not 2 = False
    not (3 & 3) = not 0011 & 0011 = not 3 = False
    

    【讨论】:

    • 按照您的解释方式理解。但是二进制字符串中的所有位都会被评估,否则not(4 & 2)not (4 & 4 ) 将评估相同的结果,如果只评估最后一位。
    • 这是真的,但不知道二进制 & 运算符的工作原理肯定有一种方法可以做到这一点
    【解决方案2】:

    位运算符通常用于在操作数之间逐位进行逻辑运算,从左到右使用对应的索引(相同权重)位。

    你必须考虑操作数的二进制表示

    例子:

    >>> bin(4 & 6)
    '0b100'
    >>> bin(4)
    '0b100'
    >>> bin(6)
    '0b110'
    >>> bin(4 & 6)
    '0b100'
    >>> bin(8)
    '0b1000'
    >>> bin(4 & 8)
    '0b0'
    >>> bin(4 | 8)
    '0b1100'
    >>>
    

    通常您不会将这些操作数与逻辑操作数混合,但这是不常见的。

    位运算符在考虑二进制或十六进制术语时非常有用,也适用于一组标志的紧凑表示。

    示例(伪造):

    单个字节的打印机状态,其中位 0 为 1 表示在线,0 表示离线。位 1 为 1 表示卡纸,0 纸张正常。位 3 为 1,表示打印机就绪。你不关心其他 5 位。

    假设

    status = 0b10100101
    

    看最后三位:0b101 表示在线,paper ok,准备好了

    将其设置为离线(强制位 0 为 0)

    status = status & 0b11111110 # same as status = status & 254
    

    摆脱你不在乎的状态

    my_status = status & 0b00000111 # same as my_status = status & 7
    

    将标志设置为 1,但将不关心的标志保留为原始值

    status = status | 0b00000111
    

    这里的0b 数字有时用十六进制表示法或什至十进制写(在这种情况下,让它们以神奇的方式进入阅读者的眼睛,而二进制和十六进制向读者明确表示位值)数字是已知的作为位掩码。它根据掩码值和按位运算符设置/取消设置所需位并保留其余位(| 设置和& 重置)

    现在您看到在处理TrueFalse0 和空/非空对象时,您所知道的逻辑运算符的规则有些不同...

    【讨论】:

      猜你喜欢
      • 2020-08-09
      • 1970-01-01
      • 1970-01-01
      • 2010-11-07
      • 2012-07-11
      • 2021-12-24
      • 2021-12-17
      • 2017-07-29
      相关资源
      最近更新 更多