在Python中使用二进制表示构建二进制数列表

时间:2011-09-05 11:47:05

标签: python list binary

我有一个非常大的0和1的列表,表示为整数 - 默认情况下 - 由python,我认为:[randint(0, 1) for i in range(50*98)]

我想优化代码,以便它使用更少的内存。显而易见的方法是仅使用1位来表示这些数字。

是否可以在python中构建真实二进制数列表?

此致 布鲁诺

编辑:谢谢大家。
从我发现的答案中我发现默认情况下Python没有这样做,所以我发现这个库(由Macports在OSX上安装,因此它省去了一些麻烦),它做了位操作: python-bitstring

5 个答案:

答案 0 :(得分:4)

这使用bitstring模块并从列表中构造BitArray对象:

from bitstring import BitArray
b = BitArray([randint(0, 1) for i in range(50*98)])

在内部,它现在以字节形式存储,因此占用的内存要少得多。您可以使用常用符号进行切片,索引,检查和设置位等,并使用其他方法(例如setallany来修改位。

要将数据作为二进制字符串返回,只需使用b.bin并使用b.tobytes()获取字节打包数据,这将填充零位到字节边界。

答案 1 :(得分:2)

正如delnan在评论中所说,如果你的意思是逐位等效的内存使用,你将无法使用实际二进制数

整数(或长整数)当然是真正的二进制数,意思是你可以解决各个位(使用逐位运算符,但很容易隐藏在类中)。此外,long对象可以变得任意大,即您可以使用它们来模拟任意大的位集。如果你用Python做它不会很快,但也不是很困难,也是一个好的开始。

使用上面的二进制生成方案,您可以执行以下操作:

reduce(
    lambda (a, p), b: (b << p | a, p + 1), 
    (random.randint(0, 1) for i in range(50*98)),
    (0, 0)
)[0]

当然,random支持任意大的上边界,所以你可以这样做:

r = random.randint(0, 2**(50*98))

这并不完全相同,因为当您为自己创建每个数字时,它们中的各个二进制数字不是独立的,就像它们是独立的一样。然后,再次,知道你的pRNG工作,他们在其他情况下也不是真正独立。如果这是您关心的问题,您可能根本不应使用random模块,而应使用硬件RNG。

答案 2 :(得分:1)

它被称为位向量或位图。尝试例如BitVector。如果你想自己实现它,你需要使用数字对象而不是列表,并使用按位运算来切换位,例如。

 bitmap = 0
 bit = (1 << 24)
 bitmap |= bit  # enable bit
 bitmap &= ~bit # disable bit

答案 3 :(得分:0)

似乎你需要某种位设置。我不确定this example是否完全符合您的需求,但值得一试。

答案 4 :(得分:0)

也许你可以研究一下你的数据的无损压缩方案?据推测,这样的列表中会有很多冗余。