【发布时间】:2019-09-09 23:37:02
【问题描述】:
我需要在内存中存储大量数字。然后我需要检查会员资格。在内存效率方面,数组比列表更好。集合比用于成员检查的列表更好。我两个都需要!所以我的问题是:
1) 数组的内存效率比集合高多少? (相反,请参阅下面的结果)。 2) 是否有一种数据结构可以在集合和数组之间取得更好的平衡?类似于带符号整数类型的集合?还是一些 numpy 构造?
我用下面的脚本检查了成员资格的时间差异。 (我知道 timeit 更好,但方差足够低以至于 time 没问题):
import array
import time
class TimerContext:
def __enter__(self):
self.t0 = time.time()
def __exit__(self, *args, **kwargs):
print(time.time()-self.t0)
SIZE = 1000000
l = list([i for i in range(SIZE)])
a = array.array('I', l)
s = set(l)
print(type(l))
print(type(a))
print(type(s))
with TimerContext():
x = 99999 in l
with TimerContext():
x = 99999 in a
with TimerContext():
x = 99999 in s
结果:
<class 'list'>
<class 'array.array'>
<class 'set'>
0.0012176036834716797
0.0024595260620117188
1.430511474609375e-06
因此,对于成员资格检查,集合要快很多(请注意科学记数法)。因此,如果它们的内存占用与数组没有什么不同,我会更喜欢使用一个集合。但我不知道如何检查内存占用。
我还应该补充一点,比较集合和列表有很多问题。但是比较数组和集合我没有看到任何好的答案。
【问题讨论】:
-
如果有人知道您的真正问题,可能还有许多其他更好的解决方案。
-
sys.getsizeof表明,对于您的示例,该集合比数组大约 8 倍。 docs.python.org/3/library/sys.html#sys.getsizeof. -
列表和数组成员资格测试都是 O(n),集合是 O(1)……也有一些近似算法,这可能会有所帮助(例如 Bloom 过滤器)。如果您有任何其他可以解决问题的限制条件,您可能会有更多选择
-
google 建议 pypi.org/project/intset 可能会有所帮助...
-
Python 还带有一个
timeit模块,它与你的TimerContext做类似的事情,Jupyter/IPython 用一个很好的%timeitmagic 包装它