Python溢出错误:iter索引太大

时间:2016-09-13 12:23:21

标签: python loops iterator

我在下面的代码中遇到for循环中的大迭代器问题。它通过读取包含数字的字符串列表来生成浮点数。

def float_generator(tekstowe):
        x = ''
        for c in tekstowe:
            if c != ' ':
                x += c
            else:
                out = float(x)
                x = ''
                yield(out)

我收到“OverflowError:iter index too too”。我尝试使用非常大的数字(如搜索文件中的数十亿个值)。它的范围在某种程度上限制了for循环吗?

使用Python 2.7 64位。感谢。

1 个答案:

答案 0 :(得分:6)

看起来tekstowe是一种只实现__getitem__的序列类型,而不是__iter__,因此它使用调用__getitem__的Python迭代器包装器为0 ,然后是1,2,3等,直到__getitem__提升IndexError

作为一个实现细节,Python 2.7.11 and higher limits the value of the index passed by the iterator wrapper to LONG_MAX(在2.7.11之前,它没有被检查过边界但它仍然使用long进行索引存储,所以它将换行并开始用负数进行索引值)。这在大多数非Windows 64位版本中都不重要,其中LONG_MAX2**63 - 1(大于您可能遇到的版本),但在Windows上,C long即使在64位构建中,s仍保持32位数量,因此LONG_MAX仍为2**31 - 1,这足以在人类时间尺度内达到。

您的选择是:

  1. 更改任何类tekstowe的实现是为了给它一个真正的__iter__方法,所以当你使用它时它不会被序列迭代器包装器包装
  2. 升级到Python 3.4+,理想情况下为3.5(2.7.10 / 3.4.3及以下lacks the check for overflow entirely,但这可能意味着环绕导致无限循环; 3.4.4/3.5.0 added the check, and they use a signed size_t, testing against PY_SSIZE_T_MAX,这意味着它不会出错直到索引在任何64位构建,Windows或其他方面达到2**63 - 1
  3. 添加溢出检查的更改是为了解决Python bug #22939;序列迭代器的索引存储在3.4.0版本中发生的类型更改(从longPy_ssize_t),解析Python bug #17932