是否有类似于 C++ 中的 std::bitset 的内置位集?
Is there a builtin bitset that's similar to the std::bitset from C++?
我想在 Python 中使用一个位数组,我可以像 C++ 中的标准位集一样使用它。示例:
#include<bitset>
int main() {
std::bitset<100> numBits;
}
不过不知道Python里面有没有类似的,最好是内置的
好吧,您可以使用布尔值列表创建 "bitset":
mybitset = [True, False, False, True, False]
我缺少上下文,无法给您更合适的回复。
没有内置的东西。如果您需要这样的数据结构以便正确输出字节,并设置正确的位,例如网络协议、二进制文件结构或硬件控制,请将 True 和 False 值列表排序为一系列字节很容易实现。
也可以创建一个 class 以允许在字节数组对象中直接对内存中的位进行多次计算。然而,不太可能发生在 C++ 中的事情,你不会获得速度或内存(好的,对于大的位集你可以获得内存)优势 - Python 将处理每个位作为对 True 或 False 的完整引用对象(或完整的 0 和 1 整数),无论您在代码中做什么。
就是说,如果您有一个包含 True 和 False 值的列表,您希望将其作为位序列输出到文件中,这样的代码可能有效:
a = [True, True, False, False, False, True, ...]
with open("myfile.bin", "wb" as file):
for i, value in enumerate(a):
if not i % 8:
if i:
file.write(byte)
byte = 0
byte <<= 1
byte |= value
if i % 8:
byte <<= (8 - i % 8)
file.write(byte)
一种更复杂的方法是通过将值保存在一个 bytearray 对象中,并在设置和重置操作中计算每个位索引来为它创建一个完整的 class 支持 - 一种最简单的方法是:
class BitArray(object):
def __init__(self, lenght):
self.values = bytearray(b"\x00" * (lenght // 8 + (1 if lenght % 8 else 0)))
self.lenght = lenght
def __setitem__(self, index, value):
value = int(bool(value)) << (7 - index % 8)
mask = 0xff ^ (7 - index % 8)
self.values[index // 8] &= mask
self.values[index // 8] |= value
def __getitem__(self, index):
mask = 1 << (7 - index % 8)
return bool(self.values[index // 8] & mask)
def __len__(self):
return self.lenght
def __repr__(self):
return "<{}>".format(", ".join("{:d}".format(value) for value in self))
如您所见,这样做不会提高速度,并且您需要大量位才能从内存节省中获益。这是在交互式提示中使用上述 class 的示例:
In [50]: a = BitArray(16)
In [51]: a[0] = 1
In [52]: a[15] = 1
In [53]: a
Out[53]: <1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1>
你可以使用普通的list
;然而,这在内存方面不是很有效:在 32 位 Python 构建中,每个 "bit" 会浪费 4 个字节,而在 64 位构建中会浪费 8 个字节。这是因为列表的元素实际上是(引用)其他 Python 个对象。
Python标准库也确实内置了array
模块,存储同质值比泛型list
效率高很多,可惜不支持位作为数据类型。此外,它不提供 Set
接口。
因此,如果内存效率很重要,那么您的选择将归结为在 array
上构建您自己的 Python 位集实现,或者从 [= 安装第 3 方模块18=]
通常,您只需内置 int
class(或 python2 中的 long
)。如果您特别关心隐藏班次,可以将其包装在 class 中。
我想在 Python 中使用一个位数组,我可以像 C++ 中的标准位集一样使用它。示例:
#include<bitset>
int main() {
std::bitset<100> numBits;
}
不过不知道Python里面有没有类似的,最好是内置的
好吧,您可以使用布尔值列表创建 "bitset":
mybitset = [True, False, False, True, False]
我缺少上下文,无法给您更合适的回复。
没有内置的东西。如果您需要这样的数据结构以便正确输出字节,并设置正确的位,例如网络协议、二进制文件结构或硬件控制,请将 True 和 False 值列表排序为一系列字节很容易实现。
也可以创建一个 class 以允许在字节数组对象中直接对内存中的位进行多次计算。然而,不太可能发生在 C++ 中的事情,你不会获得速度或内存(好的,对于大的位集你可以获得内存)优势 - Python 将处理每个位作为对 True 或 False 的完整引用对象(或完整的 0 和 1 整数),无论您在代码中做什么。
就是说,如果您有一个包含 True 和 False 值的列表,您希望将其作为位序列输出到文件中,这样的代码可能有效:
a = [True, True, False, False, False, True, ...]
with open("myfile.bin", "wb" as file):
for i, value in enumerate(a):
if not i % 8:
if i:
file.write(byte)
byte = 0
byte <<= 1
byte |= value
if i % 8:
byte <<= (8 - i % 8)
file.write(byte)
一种更复杂的方法是通过将值保存在一个 bytearray 对象中,并在设置和重置操作中计算每个位索引来为它创建一个完整的 class 支持 - 一种最简单的方法是:
class BitArray(object):
def __init__(self, lenght):
self.values = bytearray(b"\x00" * (lenght // 8 + (1 if lenght % 8 else 0)))
self.lenght = lenght
def __setitem__(self, index, value):
value = int(bool(value)) << (7 - index % 8)
mask = 0xff ^ (7 - index % 8)
self.values[index // 8] &= mask
self.values[index // 8] |= value
def __getitem__(self, index):
mask = 1 << (7 - index % 8)
return bool(self.values[index // 8] & mask)
def __len__(self):
return self.lenght
def __repr__(self):
return "<{}>".format(", ".join("{:d}".format(value) for value in self))
如您所见,这样做不会提高速度,并且您需要大量位才能从内存节省中获益。这是在交互式提示中使用上述 class 的示例:
In [50]: a = BitArray(16)
In [51]: a[0] = 1
In [52]: a[15] = 1
In [53]: a
Out[53]: <1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1>
你可以使用普通的list
;然而,这在内存方面不是很有效:在 32 位 Python 构建中,每个 "bit" 会浪费 4 个字节,而在 64 位构建中会浪费 8 个字节。这是因为列表的元素实际上是(引用)其他 Python 个对象。
Python标准库也确实内置了array
模块,存储同质值比泛型list
效率高很多,可惜不支持位作为数据类型。此外,它不提供 Set
接口。
因此,如果内存效率很重要,那么您的选择将归结为在 array
上构建您自己的 Python 位集实现,或者从 [= 安装第 3 方模块18=]
通常,您只需内置 int
class(或 python2 中的 long
)。如果您特别关心隐藏班次,可以将其包装在 class 中。