2016-09-13 9 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数(検索されたファイルの何十億もの値のような)を使用しようとします。ループのためにiter範囲が何とか制限されていますか?

Python 2.7を使用64ビット。ありがとう。 tekstoweのみ__getitem__なく、__iter__を実装する配列型であるので、それは等0と__getitem__、次いで、1、2、3、呼び出しPythonのイテレータラッパーを使用しているよう__getitem__IndexErrorを上げるまで

+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

が見えます。実装の詳細として

Python 2.7.11 and higher limits the value of the index passed by the iterator wrapper to LONG_MAX(2.7.11前に、それは境界が確認されなかったが、それはラップと負の値を持つインデックス作成を開始しますので、それはまだ、インデックスの保存のためにlongを使用)。これはLONG_MAX2**63 - 1(あなたが遭遇するよりも大きい)であるほとんどのWindows以外の64ビットビルドでは問題ありませんが、WindowsではC longは64ビットビルドでも32ビットのままなので、LONG_MAX2**31 - 1のままです。人間のタイムスケールでは十分に低くなっています。

あなたのオプションは次のとおりです。

  1. 変更どんなクラスtekstoweの実装はそれを本当の__iter__方法を与えることですので、あなたが
  2. アップグレードをそれを使用する場合には、シーケンスイテレータラッパーによってラップされません。理想的には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に達するまでエラーにならないことを意味します)

オーバーフローチェックを追加する変更が行われ、Python bug #22939が解決されました。シーケンスイテレータのインデックスストレージのタイプ変更(longPy_ssize_t)が、3.4.0のリリースで発生し、Python bug #17932を解決しました。

関連する問題