total = 0
x = 2**32
for i in range(x):
total = total + i;
print(total)
我在循环到 2**32
范围时遇到了 MemoryError
。有什么方法可以在不耗尽内存的情况下进行迭代?
最佳答案
这是当您尝试创建包含前 2 个32 个非负整数的列表时发生的情况(我在 Windows 10 系统上使用 Python 2.7.11):
>>> for i in range(2**32): pass
...
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
OverflowError: range() result has too many items
人们可能会认为,如果问题是在内存中同时拥有如此大量的项目,那么解决方案可能是通过生成器一次处理一个项目……但事实并非如此:
>>> for i in xrange(2**32): pass
...
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
OverflowError: Python int too large to convert to C long
xrange() 的文档内置函数解释了为什么会出现此错误:
CPython implementation detail: xrange() is intended to be simple and fast. Implementations may impose restrictions to achieve this. The C implementation of Python restricts all arguments to native C longs (“short” Python integers), and also requires that the number of elements fit in a native C long.
问题是 232 不能作为输入参数传递给 xrange
因为该数字大于 Python 中的最大“短”整数。试试这个说服自己:
>>> import sys
>>> sys.maxint # 2**31 - 1
2147483647
>>> sys.maxint + 1 # 2**31 is automatically converted to "long" int
2147483648L
>>> 2**31
2147483648L
如果您需要重复执行计算超过 231 次(在以下示例中为 234 次),您可以使用嵌套 for 循环:
>>> loops = 0
>>> for i in xrange(2**4):
... for j in xrange(2**30):
... # do stuff
... loops += 1
...
>>> loops
17179869184L
>>> 2**34
17179869184L
上面的代码是一个相当幼稚的变通方法。 while 循环似乎是一个更合适的解决方案:
>>> loops = 0
>>> while loops < 2**34:
... # do stuff
... loops += 1
...
>>> loops
17179869184L
关于迭代到大范围时出现 Python 内存错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36956983/