是否有类似于 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 中。