web-dev-qa-db-ja.com

pythonのメモリエラー

Traceback (most recent call last):
File "/run-1341144766-1067082874/solution.py", line 27, in 
main()
File "/run-1341144766-1067082874/solution.py", line 11, in main
if len(s[i:j+1]) > 0:
MemoryError
Error in sys.excepthook:
Traceback (most recent call last):
File "/usr/lib/python2.7/dist-packages/apport_python_hook.py", line 64, in apport_excepthook
from apport.fileutils import likely_packaged, get_recent_crashes
File "/usr/lib/python2.7/dist-packages/apport/__init__.py", line 1, in 
from apport.report import Report
MemoryError

Original exception was:
Traceback (most recent call last):
File "/run-1341144766-1067082874/solution.py", line 27, in 
main()
File "/run-1341144766-1067082874/solution.py", line 11, in main
if len(s[i:j+1]) > 0:
MemoryError

上記のエラーは、次のプログラムを実行しようとしたときに表示されました。誰かがメモリエラーとは何か、この問題を克服する方法を説明できますか? 。 プログラムは入力として文字列を取得し、すべての可能なサブ文字列を見つけて、(辞書順で)セットを作成し、ユーザーが要求したそれぞれのインデックスで値を印刷する必要があります

def main():
    no_str = int(raw_input())
    sub_strings= []
    for k in xrange(0,no_str):
        s = raw_input()
        a=len(s)
        for i in xrange(0, a):
            for j in xrange(0, a):
                if j >= i:
                    if len(s[i:j+1]) > 0:
                        sub_strings.append(s[i:j+1])
    sub_strings = list(set(sub_strings))
    sub_strings.sort()
    queries= int(raw_input())
    resul = []
    for i in xrange(0,queries):
        resul.append(int(raw_input()))
    for p in resul:
        try:
            print sub_strings[p-1]
        except IndexError:
            print 'INVALID'


if __== "__main__":
   main()
35
sachin irukula

これはここにあります:

s = raw_input()
a=len(s)
for i in xrange(0, a):
    for j in xrange(0, a):
        if j >= i:
            if len(s[i:j+1]) > 0:
                sub_strings.append(s[i:j+1])

大きな文字列には非常に非効率的で高価なようです。

やったほうがいい

for i in xrange(0, a):
    for j in xrange(i, a): # ensures that j >= i, no test required
        part = buffer(s, i, j+1-i) # don't duplicate data
        if len(part) > 0:
            sub_Strings.append(part)

バッファオブジェクトは、元の文字列と開始および長さ属性への参照を保持します。このように、データの不必要な重複は発生しません。

長さlの文字列には、平均長l*l/2l/2サブ文字列があるため、メモリ消費量はおおよそl*l*l/4になります。バッファを使用すると、はるかに小さくなります。

buffer()は2.xにのみ存在することに注意してください。 3.xにはmemoryview()があり、これはわずかに異なります。

さらに良いのは、インデックスを計算し、必要に応じて部分文字列を切り取ることです。

19
glglgl

予期しないMemoryErrorが表示され、RAMが十分にあるはずだと思われる場合は、32ビットpythonインストールを使用している可能性があります。

64ビットオペレーティングシステムを使用している場合の簡単な解決策は、Pythonの64ビットインストールに切り替えることです。

問題は、32ビットpythonが〜4GBのRAMにしかアクセスできないことです。オペレーティングシステムのオーバーヘッドのため、オペレーティングシステムが32ビットの場合、これはさらに縮小する可能性があります。

32ビットオペレーティングシステムがRAMの最大4GBに制限されている理由については、こちらをご覧ください: https://superuser.com/questions/372881/is-there-a-technical- reason-why-32-bit-windows-is-limited-to-4gb-of-ram

26
mgoldwasser

メモリエラー は、プログラムのメモリが不足したことを意味します。これは、プログラムが何らかの形で作成するオブジェクトが多すぎることを意味します。

この例では、大量のメモリを消費する可能性のあるアルゴリズムの部分を探す必要があります。あなたのプログラムには、入力として非常に長い文字列が与えられていると思います。したがって、s[i:j+1]は、新しいリストを作成するため、犯人になる可能性があります。ただし、初めて使用する場合は、作成したリストを使用しないため、必要ありません。次のことが役立つかどうかを確認できます。

if  j + 1 < a:
    sub_strings.append(s[i:j+1])

2番目のリストの作成を置き換えるには、 glglgl で提案されているように、必ず buffer オブジェクトを使用する必要があります。

また、if j >= i:を使用するため、xrangeを0から開始する必要がないことに注意してください。

for i in xrange(0, a):
    for j in xrange(i, a):
        # No need for if j >= i

より根本的な代替案は、可能なすべての部分文字列を事前に計算しないように、アルゴリズムを作り直すことです。代わりに、尋ねられた部分文字列を単純に計算できます。

8
Rodrigue

そのエラーをポップアップ表示するのと同じスクリプトを作成して、外部スクリプトからインポートすることでスクリプトを複数のスクリプトに分割することができます。たとえば、hello.pyはエラーメモリエラーを予期しているため、hello.pyをいくつかのスクリプトに分割しますh.py e.py ll.py o.pyそれらはすべて、「hellohello」というフォルダーに入り、createフォルダーに入ります- init。py initにimport h、e、ll、oを書き込み、次にideにimport hellohelloを書き込みます

1
joshua