【问题标题】:Extremely large Boolean list in PythonPython中非常大的布尔列表
【发布时间】:2009-10-16 19:21:27
【问题描述】:

我想在 python 中创建一个对象,它是大约 200,000,000 个真/假值的集合。这样我就可以最有效地更改或回忆任何给定的真/假值,以便我可以快速确定任何给定的数字,例如 123,456,000 是真还是假,或者更改它的值。

最好的方法是做这个列表吗?还是一个数组?还是一堂课?或者只是使用位操作的长整数?还是别的什么?

我有点菜鸟,所以与我用我更熟悉的其他一种语言提出问题相比,您可能需要为我详细说明问题。请举例说明对这个对象进行操作的外观。

谢谢

【问题讨论】:

  • 真/假值是密集还是稀疏?它们是均匀分布的,还是可能更密集和更稀疏的范围?数据结构的理想选择因这些而异。当然你可能不需要“理想”。

标签: python arrays list


【解决方案1】:

您可以尝试bitarray 模块,或者自己使用整数的array 编写类似的东西。

【讨论】:

【解决方案2】:

“快速确定任何给定的数字,如 123,456,000 是”在“真”集合或“假”集合中。

这就是set 的用途。

“真”集合是所有数字的集合。

要使数字的布尔标志为“真”,请将其添加到真集。

要使数字的布尔标志为“假”,请将其从真集合中删除。

生活会简单得多。

【讨论】:

  • +1:它使用简单,对于稀疏列表可能足够高效
  • 假设一半的值是真的。 int 对象的大小为 12 个字节,即 1.2GB 仅用于存储键 + 实际哈希表的额外内存。使用位数组,内存使用量为 25MB。我认为这是一个很大的区别。
  • @Lukáš Lalinský:你的分析很好。但是,除非您的处理器没有可用内存,否则我认为这无关紧要。在大多数现代处理器上,内存都很充足,25M 与 1.2G 的区别并不大。
  • 好吧,我很难将浪费 1GB 的 RAM 称为做某事的最佳方式。 :) 当然,这是一种简单的方法,如果你的真值比假值少得多,它也很有效,但这不是最好的方法。
  • 由于 RAM 不是消耗性资源,我不能对它应用“浪费”——除非你将它从处理器中拆下来扔掉。记忆是一种资源,就像时间一样,它是权衡等式的一部分。内存——在这种情况下——可以用来减少尝试管理位数组中各个位的时间。
【解决方案3】:

您是否考虑过使用像 SQLite 这样的轻量级数据库?

【讨论】:

  • +1。 2 亿位大约是 24 兆字节的数据——虽然这可以很容易地放入现代机器的内存中,但只要你在内存中达到那种大小的结构,你可能至少需要考虑数据库是否是一个更好的解决方案。
【解决方案4】:

您可能还想尝试使用纯 Python 的 bitstring 模块。在内部,它全部存储为字节数组,并为您完成位掩码和移位:

from bitstring import BitArray
# Initialise with two hundred million zero bits
s = BitArray(200000000)
# Set a few bits to 1
s.set(1, [76, 33, 123456000])
# And test them
if s.all([33, 76, 123456000]):
    pass

其他海报是正确的,尽管简单的集合可能是解决您特定问题的更好解决方案。

【讨论】:

    【解决方案5】:

    乍一看,Python BitVector 模块听起来完全符合您的要求。它可以在http://cobweb.ecn.purdue.edu/~kak/dist/BitVector-1.5.1.html 获得,因为它是纯 Python 代码,它可以在任何平台上运行,无需编译。

    您提到在获取和设置任意真假值时需要一些速度。为此,您需要使用 Python 数组,而不是列表,如果您转到上述 URL 并浏览 BitVector 的源代码,您会发现它确实依赖于 Python 数组。

    理想情况下,您可以将您正在做的事情封装在一个从 BitVector 子类化的类中,即

    class TFValues(BitVector):
       pass
    

    这样您就可以添加一个列表以包含相关信息,例如特定 TF 值的名称。

    【讨论】:

      【解决方案6】:

      如果设置的位大多是连续的,还有存储范围列表的选项,例如PyPI 模块 https://pypi.org/project/range_set/ 与 Python 的 set 类 API 兼容。

      【讨论】:

        猜你喜欢
        • 2015-08-18
        • 2012-04-08
        • 2018-02-19
        • 1970-01-01
        • 2014-01-30
        • 1970-01-01
        • 2015-10-21
        • 2013-03-24
        • 2020-03-22
        相关资源
        最近更新 更多