按位运算 Python

Bitwise operations Python

这是第一个 运行-in,不仅在 python 中有按位操作,而且(对我来说)语法也很奇怪。

for i in range(2**len(set_)//2):
        parts = [set(), set()]
        for item in set_:
            parts[i&1].add(item)
            i >>= 1

对于上下文,set_ 只是一个包含 4 个字母的列表。

这里有一点需要解压。首先,我从未见过[set(), set()]。我一定是使用了错误的关键字,因为我在文档中找不到它。看起来它在 pythontutor 中创建了一个矩阵,但我不能肯定地说。其次,虽然 parts[i&1] 是一个切片操作,但我不完全确定为什么需要按位操作。比如0&1应该是1,1&1应该是0(进位),那么二进制是10(或者十进制是2)?最后,最后的位运算完全是一头雾水。我相信右移等同于除以二(我希望如此),但为什么 i>>=1?我不知道该如何解释。任何指导将不胜感激。

I've never seen [set(), set()]

这没什么有趣的,只是一个包含两个新集合的列表。所以你已经看到了,因为它不是新语法。只是一个列表和构造函数。

parts[i&1]

这将测试 i 的最低有效位并选择 parts[0](如果 lsb 为 0)或 parts[1](如果 lsb 为 1)。没有什么比切片更奇特的了,只是对列表进行简单的旧索引。你得到的是一个集合,.add(item) 做了一件显而易见的事情:在选择的集合中添加一些东西。

but why i>>=1? I don't know how to interpret that

i 中的位并将它们向右移动一位,删除旧的 lsb,并保留符号。有点像这样

当然除了 Python 你有任意精度的整数,所以它需要多长而不是 8 位。

对于正数,复制符号的部分无关紧要。

您可以将右移 1 视为除以 2(这与截断不同,负数向负无穷大四舍五入,例如 -1 >> 1 = -1),但这种解释通常更复杂关于原因。

总之,这里的使用方式只是循环遍历i的位,从低到高一个一个测试,而不是改变它测试的位,而是移动bit每次都想测试到同一个位置

[set(), set()] 创建一个由两个空集组成的列表。

0&1为0,1&1为1,按位运算没有进位。 parts[i&1] 因此,当 i 是偶数时指第一组,当 i 是奇数时指第二组。

i >>= 1右移一位(确实等同于除以2),然后将结果赋值回i。它与使用 i += 1 递增变量的基本概念相同。

内循环的作用是根据i的位,将_set的元素分成两个子集。如果外循环中的限制只是 2 ** len(_set),代码将生成所有可能的此类分区。但是由于该限制被除以二,所以只生成了一半的可能分区 - 在没有更多上下文的情况下,我无法猜测这可能是什么意思。