3

似乎这两个例外都是在类似的情况下提出的。

这两个代码行有什么区别以及在幕后发生了什么?

>>> (i for i in range(1000000000)) # 10^9
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
MemoryError
>>> (i for i in range(10000000000)) # 10^10
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
OverflowError: range() result has too many items
4

2 回答 2

4

在第一个示例中,您尝试将 1,000,000,000 个整数的列表传递给生成器表达式。您的计算机在尝试创建该列表时内存不足。在 Python 3 中,我怀疑这会起作用,因为range它本身会生成生成器而不是显式列表。

在第二个示例中,我怀疑range它在您的机器上的输入需要一个 32 位的值,因此在内存不足之前会引发不同的错误。

于 2013-07-24T13:29:55.223 回答
2

从文档:

异常溢出错误

当算术运算的结果太大而无法表示时引发。这不会发生在长整数(宁愿引发 MemoryError 而不是放弃)和大多数使用纯整数的操作中,而是返回长整数。由于 C 中浮点异常处理缺乏标准化,大多数浮点运算也没有被检查。

异常内存错误

当操作耗尽内存时引发,但情况仍然可以挽救(通过删除一些对象)。关联的值是一个字符串,指示哪种(内部)操作耗尽了内存。请注意,由于底层内存管理架构(C 的 malloc() 函数),解释器可能并不总是能够完全从这种情况中恢复;尽管如此,它还是会引发异常,以便可以打印堆栈回溯,以防程序失控。

在 Python 2 中,range(1000000000)生成一个包含1000000000元素的列表,这会导致内存不足。如果您替换rangexrange,问题就会消失,因为您使用的是生成器。

在第二个例子中,1000000000实际上是一个long。如果你使用xrange,你会得到:

>>> (i for i in xrange(10000000000))
OverflowError: long int too large to convert to int
于 2013-07-24T13:23:15.617 回答