进行位差分的正确方法?(python 2.7)

进行位差分的正确方法?(python 2.7),python,set,bit-manipulation,bitwise-operators,Python,Set,Bit Manipulation,Bitwise Operators,我将值集存储为python长整数,以不同的2**I和的形式,因为python允许对其整数进行逐位运算。对于我的许多程序来说,这比使用数据结构快得多 我经常发现自己想要取两个位值的差 例如: 假设我有两个值,由2和4表示。通过并集,它们形成一个集合,值为6。(110) 然后我有第二个集合,十进制值10(二进制1010),即2和8 我想找到第一个集合中的值,而不是第二个集合中的值。如果我使用集合结构,我会取集合差。但我用的是整数。如果我尝试做一些改变,它将不起作用(它将是-4) 到目前为止,我发现自

我将值集存储为python长整数,以不同的2**I和的形式,因为python允许对其整数进行逐位运算。对于我的许多程序来说,这比使用数据结构快得多

我经常发现自己想要取两个位值的差

例如:

假设我有两个值,由2和4表示。通过并集,它们形成一个集合,值为6。(110) 然后我有第二个集合,十进制值10(二进制1010),即2和8

我想找到第一个集合中的值,而不是第二个集合中的值。如果我使用集合结构,我会取集合差。但我用的是整数。如果我尝试做一些改变,它将不起作用(它将是-4)


到目前为止,我发现自己在做value1-(value1和value2)。这需要两个单独的操作才能找到差异。有没有一种方法可以利用python提供的功能在一个操作而不是两个操作中快速完成这项工作?

不是在一个操作中完成,但是您应该坚持使用位操作(不是
+
-
)。如果希望
value1
中的位不是
value2
中的位,通常的拼写方法是

value1 & ~value2

也就是说,
value1
value2
的补码的交集(注意这里的一元前缀操作符是
~
,而不是
-
)。

集差
B-A
只是
B
A
的补码的交集

而且,虽然没有按位差分运算符,但有按位交集(
&
)和按位补码(
~
)运算符。因此:

b_minus_a = b & ~a
或者,以您的例子:

>>> b, a = 0b110, 0b1010
>>> b & ~a
4
>>> bin(_)
0b100

当然,您可以将其封装在函数中:

def bitsetdiff(b, a):
    return b & ~a

但是,如果你要做很多这类事情,而按位运算不是自然而然的,你可能想在PyPI中搜索和的库,这将给你一个对象,它的行为类似于一组布尔值,但存储为(并且可以有效地转换为)整数

我选择它是因为它看起来很有前途:

>>> b = intbitset([2, 4])
>>> a = intbitset([2, 8])
>>> b - a
intbitset([4])

就像使用集合一样。但我看不到任何明显的方法可以将值作为一个大整数来访问。可能还有其他更适合你需要的图书馆;我只是在快速扫描后才选择了一个。

如果您发现处理位非常复杂,您可能需要使用第三方库,如
位集
位集
或…PyPI上似乎有一些位集,请搜索并查看所有位集。但无论如何,他们会给你一个对象,它的行为就像一组位,具有正常的集合操作,但由一个大整数表示(并且可以转换为整数或从整数转换而来)。预期值为4I(在现在删除的答案中),但它也是两个操作。我只是很高兴知道肯定没有办法在一个操作中完成(或者如果有,它将是一个facade:P)。我接受答案。@wim如果您定义了一个函数,那么调用该函数只是代码中的一个操作。如果使用位集库,可以直接编写
b-a
而不是
bitsetdiff(b,a)
。当然,在幕后,它做的不仅仅是一个位运算,但是在幕后,即使是
a&b
也在做不止一个位操作,它正在查找并调用一个特殊的方法,该方法最终被实现为在
int
对象下面的数字的zip上映射一个位操作,并构建一个新的
int
对象…