在我的python代码中,我有以下行
vals = [True] * n
当n
是一个较小的数字时,此代码有效但我希望在n ~ 100,000,000
没有获得MemoryError
我甚至尝试使用这样的词典,但它仍然无法正常工作
vals = {}
for i in range(0, n):
vals[i] = True
有什么建议吗?
修改
对于那些你想知道我想要做什么的人。我正在尝试实现Sieve of Eratosthenes算法来生成素数。 vals
变量会跟踪稍后在算法
编辑2 我不这么认为我可以使用生成器,因为我需要稍后更改值,如下所示:
vals = [True] * n
for i in range(0, n):
if condition:
vals[i] = False
答案 0 :(得分:3)
使用numpy
您可以处理大型列表:
import numpy as np
vals = np.ones(100000000,bool)
print(vals)
# [ True True True ..., True True True]
答案 1 :(得分:1)
不要将所有数据保存在内存中,只保留当前所需的数据或保留其他表示形式,以便即时生成。
在这种情况下,您应该使用“稀薄的空气”表示:
或者,您可以将数据卸载到磁盘,例如使用偏移来访问元素(这将是相当慢的)或编写具有类似列表的接口的类,该类将使用磁盘和缓存,在需要时加载和卸载数据(mmap
是IMO的良好支持选择)。
答案 2 :(得分:0)
您可以使用发电机
vals = lambda n: (True for _ in range(n))
编辑:因为OP要求实施numpy
n = 100000000
prime = lambda n: list(filter(lambda x: (x % np.arange(2, 1+int(math.sqrt(x)))).all(), range(2, n+1)))
答案 3 :(得分:0)
您可能想要使用生成器:
def vals():
for i in range(0, n):
yield True
为了与Python 2.x兼容,最好使用xrange
:
try:
xrange
except NameError:
xrange = range
def vals():
for i in xrange(0, n):
yield True
否则,如果使用较旧的解释器运行,您的程序将无声地耗尽资源。
答案 4 :(得分:-2)
检查这些:
http://stromberg.dnsalias.org/~strombrg/bits_mod/
http://stromberg.dnsalias.org/~strombrg/sieve/
第一种是使用至少31位多个整数的位数组类型。
第二个是基于该位阵列类型的筛子。
如果你仍然需要一些不适合内存的东西,你可能会考虑修改bits_mod来使用mmap,例如:http://stromberg.dnsalias.org/~strombrg/drs-bloom-filter/
这里有一些时间信息,使用pypy3 2.4.0,如果你决定走numpy路线,但仍然好奇pypy3可以做什么:
$ time ./sieve 100000000 > /dev/null
Creating bit array
Clearing multiples of 2
Clearing multiples of 3
Clearing multiples of 5
Clearing multiples of 7
...
Clearing multiples of 9931
Clearing multiples of 9941
Clearing multiples of 9949
Clearing multiples of 9967
Clearing multiples of 9973
real 1m10.749s
user 1m8.133s
sys 0m2.405s