2016-09-13 93 views
3

我在下面的代碼中有for循環中的大迭代器的問題。它通過讀取包含數字的字符串列表來生成浮點數。Python溢出錯誤:iter索引太大

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

我得到一個「OverflowError:ITER指數過大」。我嘗試使用真正的大數字(比如在搜索文件中的數十億個值)。某種程度上,iter的範圍限制在for循環中?

使用Python 2.7 64位。謝謝。

+0

float(x)'有多大? –

+0

他們是0-255的價值,看起來像這樣隨機: 25.75000000 0.340 22.33333397 0.667。我的意思是這些是4個示例浮游物。 –

+0

答案在這裏https://github.com/python/cpython/blob/efac0438f42e03f0ece269ac8f1616bc6dc2d8bd/Objects/iterobject.c#L57和這裏https://docs.python.org/2/c-api/long.html# c.PyLong_AsSsize_t –

回答

4

貌似tekstowe是隻實現__getitem__,不__iter__序列類型,所以它的使用Python迭代包裝調用__getitem__與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上,即使在64位版本上,C long仍保持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,這意味着它不會錯誤,直到索引達到2**63 - 1在任何64位版本,Windows或其他)

添加溢出檢查的更改已解決Python bug #22939;序列迭代器索引存儲的類型更改(從longPy_ssize_t)發生在3.4.0版本中,解析爲Python bug #17932