我有一个非常大的0和1的列表,表示为整数 - 默认情况下 - 由python,我认为:[randint(0, 1) for i in range(50*98)]
我想优化代码,以便它使用更少的内存。显而易见的方法是仅使用1位来表示这些数字。
是否可以在python中构建真实二进制数列表?
此致 布鲁诺
编辑:谢谢大家。
从我发现的答案中我发现默认情况下Python没有这样做,所以我发现这个库(由Macports在OSX上安装,因此它省去了一些麻烦),它做了位操作:
python-bitstring
答案 0 :(得分:4)
这使用bitstring模块并从列表中构造BitArray
对象:
from bitstring import BitArray
b = BitArray([randint(0, 1) for i in range(50*98)])
在内部,它现在以字节形式存储,因此占用的内存要少得多。您可以使用常用符号进行切片,索引,检查和设置位等,并使用其他方法(例如set
,all
和any
来修改位。
要将数据作为二进制字符串返回,只需使用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)
也许你可以研究一下你的数据的无损压缩方案?据推测,这样的列表中会有很多冗余。