内存错误Python

时间:2015-09-22 15:24:25

标签: python python-2.7 montecarlo

我正在尝试处理蒙特卡罗算法来计算pi的值。当我尝试提供如下程序中提到的大量输入时。我收到内存错误。我该怎么做才能纠正它?代码如下:

def PiCalc():
    N_ok=0  
    n=1000000000000 

    for i in range(n):  
        x=random()  
        y=random() 

        if sqrt(x**2 + y**2) <= 1:  
            N_ok+=1  
    pi= 4.0 * N_ok / n 

    print "No. of points inside the circle: ", N_ok
    print "Pi: ", pi
    return pi 

4 个答案:

答案 0 :(得分:5)

在Python 2.7 range(n)中将创建一个包含1000000000000个元素的列表,这会导致MemoryError

使用xrange(n)您可以随时生成项目

根据文件:

  

xrange(开始,停止[,步骤])   此函数与range()非常相似,但返回xrange对象而不是list。这是一个不透明的序列类型,它产生与相应列表相同的值,而不是实际同时存储它们。 xrange()在range()上的优势是最小的(因为xrange()在被要求时仍然需要创建值)

答案 1 :(得分:5)

鉴于没人提到这一点......

您也可以使用itertools.repeat(None, n)。这将比rangexrange快得多,因为它不会创建一个新的int实例。

使用repeat(),您的for循环变为:

for _ in itertools.repeat(None, n):
    x=random()
    y=random()
    if x**2 + y**2 <= 1:
        N_ok += 1

答案 2 :(得分:2)

由于您使用print的方式,我假设您使用的是Python 2.x.在Python 2.x中,range返回一个列表。所以你试图在内存中建立一个1000000000000整数的列表。这里的内存错误是正常的。

你应该尝试:

for i in xrange(n):  

因为xrange返回一个xrange对象(*)并且没有在内存中构建列表。

(*)它允许迭代值,但它实际上不是迭代器(感谢DSM的精度)

答案 3 :(得分:1)

我要创建一个函数:

def random_pairs(n):
    for _ in itertools.repeat(None, n):
        yield random(), random()

N = sum(1 for (x, y) in random_pairs(n)
        if x**2 + y**2 <= 1.)