【问题标题】:Building a list with binary numbers in binary representation in Python在 Python 中以二进制表示的二进制数构建一个列表
【发布时间】:2011-11-10 13:54:40
【问题描述】:

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

我想优化代码,使其占用更少的内存。显而易见的方法是仅使用 1 位来表示这些数字中的每一个。

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

问候, 布鲁诺

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

【问题讨论】:

  • “实二进制数”和“正常数”有什么区别?
  • 您的意思是位集/位串吗? stackoverflow.com/questions/3946086/…
  • 一个真正的二进制数只使用 1 位内存。据我所知,一个普通的数字,也就是一个整数,在 Python 中至少使用了 16 位。
  • 无论使用何种语言,您都无法处理任何内存。如果你想要一个 N 位数,N 必须是 8 的倍数,即使你忽略它们。
  • 内存真的是个问题,还是您只是认为有问题? 50*98 位是相当小的内存量。

标签: python list binary


【解决方案1】:

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

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

现在它在内部被打包存储为字节,因此占用的内存要少得多。您可以使用通常的符号对位进行切片、索引、检查和设置等操作,并且还有其他方法(例如setallany)来修改位。

要以二进制字符串的形式取回数据,只需使用b.bin,要取出字节打包数据,请使用b.tobytes(),它将用零位填充到字节边界。

【讨论】:

  • 非常感谢,您帮助我阅读了 bitstring 的文档。这正是我将使用的。
【解决方案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。

【讨论】:

    【解决方案3】:

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

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

    【讨论】:

    • 谢谢,我正在寻找类似的东西。在从 Python 没有在标准安装中提供的答案中理解之后,我确实找到了一个库(由 Macports 在 OSX 上安装,所以它为我省去了一些麻烦),它可以进行位操作。 python-bitstring
    【解决方案4】:

    看来您需要某种位集。我不确定this example 是否完全符合您的需求,但值得一试。

    【讨论】:

    • 谢谢。我找到了一个执行位操作的库(由 Macports 在 OSX 上安装,因此可以省去一些麻烦)。 python-bitstring
    【解决方案5】:

    也许您可以为您的数据研究一种无损压缩方案?想必这样的列表会有很多冗余。

    【讨论】:

    • 确实如此,但尽管字符串有点大,但它们并没有那么大,无法补偿使用压缩的开销。
    • 如果位数组是随机生成的,无论如何都不会有任何冗余可以压缩掉。
    • @vhallac:如果我按照自己的意愿去做并且只使用位,那就是真的。但亚历克斯也是对的,因为如果我必须用整数表示日期中的 0 和 1,那么,即使是随机压缩也会有所帮助。但即便如此,使用位操作看起来更简单。谢谢。
    • @jbbsm 好点。我从来没有想过压缩包含位的整数。与您能想到的任何压缩方法相比,明显的位打包“压缩”几乎是微不足道的——而且性能会更好。 :)
    猜你喜欢
    • 1970-01-01
    • 2017-06-23
    • 2016-01-01
    • 2021-10-06
    • 2012-02-10
    • 1970-01-01
    • 2018-03-20
    • 1970-01-01
    • 2018-08-03
    相关资源
    最近更新 更多