it-swarm.com.de

speicherfehler in 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

Die obigen Fehler traten auf, als ich das folgende Programm ausführen wollte. Kann jemand erklären, was ein Speicherfehler ist und wie man dieses Problem lösen kann? . Das Programm nimmt Strings als Eingabe und findet alle möglichen Unterstrings und erstellt daraus einen Satz (in lexikographischer Reihenfolge). Es sollte den Wert an dem vom Benutzer angeforderten Index ausgeben. Andernfalls wird 'Invalid' ausgegeben.

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()
26
sachin irukula

Dieses hier:

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])

scheint für große Saiten sehr ineffizient und teuer zu sein.

Besser machen

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)

Ein Pufferobjekt enthält einen Verweis auf die ursprüngliche Zeichenfolge sowie Start- und Längenattribute. Auf diese Weise tritt keine unnötige Duplizierung von Daten auf.

Eine Zeichenfolge der Länge l hat l*l/2 Unterzeichenfolgen der durchschnittlichen Länge l/2, sodass der Speicherverbrauch ungefähr l*l*l/4 wäre. Mit einem Puffer ist es viel kleiner.

Beachten Sie, dass buffer() nur in 2.x vorhanden ist. 3.x hat memoryview(), was etwas anders verwendet wird.

Noch besser wäre es, die Indizes zu berechnen und den Teilstring bei Bedarf auszuschneiden.

17
glglgl

Wenn Sie eine unerwartete MemoryError erhalten und denken, Sie sollten RAM verfügbar haben, könnte dies daran liegen, dass Sie eine 32-Bit-Python-Installation verwenden. 

Wenn Sie ein 64-Bit-Betriebssystem haben, können Sie einfach auf eine 64-Bit-Installation von Python umsteigen.

Das Problem ist, dass 32-Bit-Python nur Zugriff auf ~ 4 GB RAM hat. Bei Betriebssystemen mit 32 Bit kann dies aufgrund des Betriebssystem-Overheads sogar noch weiter schrumpfen. 

Mehr darüber, warum 32-Bit-Betriebssysteme auf ~ 4 GB RAM beschränkt sind, erfahren Sie hier: https://superuser.com/questions/372881/is-there-a-technical-reason-why- 32-Bit-Fenster sind auf 4 GB RAM begrenzt

19
mgoldwasser

Ein Speicherfehler bedeutet, dass der Speicher Ihres Programms nicht ausreicht. Dies bedeutet, dass Ihr Programm irgendwie zu viele Objekte erstellt.

In Ihrem Beispiel müssen Sie nach Teilen Ihres Algorithmus suchen, die viel Speicherplatz benötigen. Ich vermute, dass Ihr Programm sehr lange Zeichenfolgen als Eingabe erhält. Daher könnte s[i:j+1] der Täter sein, da eine neue Liste erstellt wird. Bei der ersten Verwendung ist es jedoch nicht erforderlich, da Sie die erstellte Liste nicht verwenden. Sie könnten versuchen zu sehen, ob folgende Punkte hilfreich sind:

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

Um die zweite Listenerstellung zu ersetzen, sollten Sie auf jeden Fall ein buffer object verwenden, wie von glglgl vorgeschlagen.

Beachten Sie außerdem, dass Sie, da Sie if j >= i: verwenden, Ihre xrange nicht mit 0 beginnen müssen. Sie können Folgendes haben:

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

Eine radikalere Alternative wäre, den Algorithmus so zu überarbeiten, dass nicht alle möglichen Teilketten vorberechnet werden. Stattdessen können Sie einfach den abgefragten Teilstring berechnen.

6
Rodrigue

Die Verwendung von Python 64 Bit löst viele Probleme.

1
Rajeev Kallur

sie könnten versuchen, dasselbe Skript zu erstellen, das diesen Fehler anzeigt, und das Skript durch Importieren aus einem externen Skript in mehrere Skripts aufteilen. Beispiel: hallo.py erwartet einen Fehler Speicherfehler, also teile ich hallo.py in mehrere Skripte auf. init. py in init schreiben import h, e, ll, o und dann schreiben Sie import hellohello

1
joshua