是否有类似于C ++的std :: bitset的内置bitset?

时间:2015-12-28 15:29:14

标签: python bitset

我想在Python中使用一个我可以使用的位数组,就像C ++中的标准位集一样。例如:

#include<bitset>
int main() {
    std::bitset<100> numBits;
}

但是,我不知道Python中是否有类似内容,最好是内置的。

4 个答案:

答案 0 :(得分:1)

没有内置的东西。如果您需要这样的数据结构以便正确输出字节,并设置正确的位,例如网络协议,二进制文件结构或硬件控制,则将True和False值列表排序为字节很容易实现。

还可以创建一个类,以允许直接对bytearray对象中的内存中位进行多次计算。但是,不太可能在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对象中,并在set和reset操作中计算每个位索引 - 这样做的极简主义方法是:

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))

正如您所看到的,这样做没有速度增加,并且您需要大量的位才能从中节省内存。这是交互式提示中使用的上述类的示例:

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>

答案 1 :(得分:0)

好吧,你可以做一个&#34; bitset&#34;使用布尔列表:

mybitset = [True, False, False, True, False]

我没有上下文给你一个更恰当的回应。

答案 2 :(得分:0)

你可以使用普通的list;然而,这在内存方面不是非常有效:在32位Python构建上,每个“位”会浪费4个字节,而在64位构建上会浪费8个字节。这是因为列表的元素实际上是(引用)其他Python对象。

Python标准库也有内置的array模块,它比通用list更有效地存储齐次值,但遗憾的是它不支持位作为数据类型。此外,它不提供Set接口。

因此,如果关注内存效率,那么您的选择将归结为在array上构建自己的Python bitset实现,或者从PyPI安装第三方模块,例如intbitset

答案 3 :(得分:0)

通常,你只是内置的int类(或python2中的long)。如果你特别关心隐藏班次,也许可以把它包在课堂上。