我如何在Python中表示和使用n位向量?

时间:2010-01-27 14:59:14

标签: python bit-manipulation bitarray bitvector

在我正在进行的一项任务中,我们需要使用位向量,但我不确定如何在Python中执行此操作。它们应该能够从4位到20位。我以前从未使用过位向量,但我想可以创建一个使用通常的AND / OR / XOR操作操作的无符号字节数组。

这里的重要限制是:我不能依赖除标准Python提供的之外的任何库。

我想我知道如何使用8位无符号字节的数组在C中执行此操作: 例如将零数组的第18位变为1,我会做类似的事情 my_bit_array [3]& = 1<< 2

但是由于Python是动态类型的,并且没有内置数组类型,我将如何以pythonic方式执行此操作?

是否有可能(如何?)表达大小为20的位向量?我在考虑制作一个24位/ 3字节向量并忽略4位。

7 个答案:

答案 0 :(得分:15)

我很惊讶没有人提到int(或者我猜测{2}在Python 2中)。 long可以是任意大的,你可以在它们上使用按位运算符,它们会很快,而且代码看起来像C中的代码(我认为这是一个优势)。

int

我已经将它用于数百位长的位向量。

答案 1 :(得分:8)

bitarray模块可以有效地使用布尔值。

答案 2 :(得分:7)

BitVector是一个用于此目的的纯Python库,应该适合您指定的需求。

答案 3 :(得分:4)

它有列表,你可以填充bools:

[False] * 20

答案 4 :(得分:2)

有点过时,但为了比较,我将在这里留下另一个stdlib选项。使用ctypes模块也很容易做到这一点。

例如:

  

是否有可能(如何?)表达大小为20的位向量?   我在考虑制作一个24位/ 3字节向量并忽略4   位。

class Simple(ctypes.LittleEndianStructure):
    _pack_ = 1
    _fields_ = [
                 ('one', ctypes.c_ubyte, 8),
                 ('two', ctypes.c_ubyte, 8),
                 ('three', ctypes.c_ubyte, 8)
               ]

s = Simple(0, 2, 256)
bytearray(s)        # bytearray(b'\x00\x02\x00')
s = Simple(0, 2, 255)
bytearray(s)        # bytearray(b'\x00\x02\xff')

class Simple(ctypes.BigEndianStructure):
    _pack_ = 1
    _fields_ = [
                 ('one', ctypes.c_ubyte, 8),
                 ('two', ctypes.c_ubyte, 8),
                 ('three', ctypes.c_ubyte, 8)
               ]

s = Simple(0, 2, 256)
bytearray(s)        # bytearray(b'\x00\x02\x00')
s = Simple(0, 2, 255)
bytearray(s)        # bytearray(b'\x00\x02\xff')

s.two |= 3
bytearray(s)        # bytearray(b'\x00\x03\xff')

或更直接的事情:

class bit_vector(Structure):
    _fields_ = [('bits', c_uint32, 24),
                ('unused', c_uint32, 8),
                ]

bv = bit_vector()
# turn on the 18th bit -- being explicit just to demo it
bv.bits |= int('000000000000000001000000', 2)
bin(bv.bits)   # 0b1000000

答案 5 :(得分:1)

使用struct模块。

答案 6 :(得分:1)

还有纯Python python-bitstring (支持Python 3)。