如何在 Python 中表示和使用 n 位向量?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/2147848/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How do I represent and work with n-bit vectors in Python?
提问by oligofren
In an assignment I am currently working on we need to work with bit vectors, but I am very unsure of how to do this in Python. They should be able to be from 4 bits to 20 bits. I have never worked with bit vector before, but I guess that one would one create arrays of unsigned bytes that you manipulated using the usual AND/OR/XOR operations.
在我目前正在处理的作业中,我们需要使用位向量,但我非常不确定如何在 Python 中执行此操作。它们应该能够从 4 位到 20 位。我以前从未使用过位向量,但我想有人会创建您使用通常的 AND/OR/XOR 操作操作的无符号字节数组。
The important restrictionhere is: I cannot rely on anylibraries other than those supplied with standard Python.
这里的重要限制是:除了标准 Python 提供的库之外,我不能依赖任何库。
I think I know how I would do this in C using arrays of 8 bit unsigned bytes: e.g. to turn the 18th bit of a zeroed array into a one, I would do something like my_bit_array[3] &= 1<<2
我想我知道我将如何使用 8 位无符号字节数组在 C 中执行此操作:例如,将清零数组的第 18 位转换为 1,我会执行类似 my_bit_array[3] &= 1<<2 的操作
But since Python is dynamically typed and does not have a built-in array type, how would I go about doing this in a pythonic way?
但是由于 Python 是动态类型的并且没有内置数组类型,我将如何以 Pythonic 的方式执行此操作?
And is it possible (how?) to express a bit vector of size 20? I am thinking of perhaps making a 24 bit / 3 byte vector and ignoring the 4 bits.
是否有可能(如何?)表达一个大小为 20 的位向量?我正在考虑制作一个 24 位/3 字节的向量并忽略 4 位。
采纳答案by H?vard S
回答by jpkotta
I'm surprised that no one has mentioned int
s (or I guess long
in Python 2). int
s can be arbitrarily large, you can use bitwise operators on them, they're fast, and the code looks like bit twiddling code in C (I consider that to be an advantage).
我很惊讶没有人提到int
s(或者我猜long
在 Python 2 中)。 int
s 可以任意大,您可以对它们使用按位运算符,它们很快,并且代码看起来像 C 中的位代码(我认为这是一个优势)。
x = 0 # empty
x |= 1<<19 # set bit 19
x &= ~(1<<19) # clear bit 19
x ^= 1<<19 # toggle bit 19
x = ~x # invert *all* bits, all the way to infinity
mask = ((1<<20)-1) # define a 20 bit wide mask
x &= mask # ensure bits 20 and higher are 0
x ^= mask # invert only bits 0 through 19
(x >> 19) & 1 # test bit 19
(x >> 16) & 0xf # get bits 16 through 20.
I've used this for bitvectors hundreds of bits long.
我已经将它用于数百位长的位向量。
回答by Ignacio Vazquez-Abrams
It has lists, which you can populate with bools:
它有列表,你可以用布尔值填充:
[False] * 20
回答by lonetwin
A bit dated but I'm going to leave another stdlib option here just for comparison sake. It is also easy to do this using the ctypesmodule.
有点过时,但为了比较起见,我将在这里留下另一个 stdlib 选项。使用ctypes模块也很容易做到这一点。
For example:
例如:
And is it possible (how?) to express a bit vector of size 20 ? I am thinking of perhaps making a 24 bit / 3 byte vector and ignoring the 4 bits.
是否有可能(如何?)表达大小为 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')
or something more straight forward like this:
或者像这样更直接的东西:
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
回答by Janus Troelsen
There is also the pure-Python python-bitstring(with Python 3 support).
还有纯Python python-bitstring(支持Python 3)。