迭代一个大的列表

时间:2015-01-04 03:27:04

标签: python

我有一个范围[465868129,988379794]的列表。当我使用以下代码时,我得到一个内存错误。我该怎么办?

r = [465868129, 988379794]
list = [x for x in xrange(r[0], r[1]+1)]

2 个答案:

答案 0 :(得分:4)

您可以直接迭代xrange,而不是创建列表。

for x in xrange(r[0], r[1] + 1):
    ...

但是,如此大范围的迭代是寻找方块的非常非常慢的方法。内存不足的事实应该提醒您需要采用不同的方法。

更好的方法是采用每个终点的平方根,然后在平方根之间迭代。平方根之间的每个整数,当平方时,会给你一个你正在搜索的数字。

事实上,如果你足够聪明,你可以使用单个列表理解生成所有正方形,并完全避免使用明确的for循环。

答案 1 :(得分:1)

除非你有充分的理由将列表项存储在列表中,否则迭代生成器,这样Python就不需要分配大量内存(导致内存错误)来创建该列表:

init, end = (465868129, 988379794)
items = xrange(init, end + 1)

for item in items:
    #Do something with item

要计算任意范围的方块,请考虑以下公式:

import math

number_of_squares = int(math.sqrt(end) - math.sqrt(init)) + 
                    op(is_perfect_square(init), is_perfect_square(end))

is_perfect_square(n)本身就是另一个问题,因此如果感兴趣请查看this post

op用于在间隔init (or/and/neither) end的初始化和结束为正方形时调整方格数。所以我们需要一个具有以下特征的函数:

  • 两个数字都是完美的正方形:例如:25,64 => 8 - 5 = 3(该范围内有4个方格)。 (它应该加1)
  • End是一个完美的正方形:例如:26,64 => 8 - 5 = 3(该范围内有3个方格)。 (这是正确的=>它应该总和0)
  • Init是一个完美的正方形:例如:25,65 => 8 - 5 = 3(该范围内有4个方格)。 (它应该加1)
  • 没有数字是素数:例如:26,65 => 8 - 5 = 3(该范围内有3个方格)(正确=>它应该加0)

因此,基于过去的例子,我们需要一个具有以下特征的运算符:

  • 1 op 1 = 1 (两个数字都是完美的正方形)
  • 0 op 1 = 0 (结束是完美的正方形)
  • 1 op 0 = 1 (Init是一个完美的正方形)
  • 0 op 0 = 0 (没有数字是完美的正方形)

请注意,max函数几乎满足了我们的需求,但在第二种情况下max(0,1)= 1失败,它应该为0.

所以,看起来结果只取决于第一个算子:如果是1,结果是1,另一方面,如果它是0,则返回0。

因此,考虑到这一点,编写函数很容易:

import math

number_of_squares = int(math.sqrt(end) - math.sqrt(init)) + 
                    int(is_perfect_square(init))

感谢@kojiro,我们有这种方法(有类似的想法),更容易阅读:

from math import sqrt, floor, ceil

number_of_squares = 1 + floor(sqrt(end)) - ceil(sqrt(init))