按位运算 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)
,代码将生成所有可能的此类分区。但是由于该限制被除以二,所以只生成了一半的可能分区 - 在没有更多上下文的情况下,我无法猜测这可能是什么意思。
这是第一个 运行-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)
,代码将生成所有可能的此类分区。但是由于该限制被除以二,所以只生成了一半的可能分区 - 在没有更多上下文的情况下,我无法猜测这可能是什么意思。