web-dev-qa-db-fra.com

erreur de mémoire en 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

Les erreurs ci-dessus sont apparues lorsque j'ai essayé d'exécuter le programme suivant. Quelqu'un peut-il expliquer ce qu'est une erreur de mémoire et comment surmonter ce problème? . Le programme prend les chaînes en tant qu'entrée, trouve toutes les sous-chaînes possibles et crée un ensemble (dans un ordre lexicographique). Il doit imprimer la valeur à l'index respectif demandé par l'utilisateur, sinon il doit afficher 'Non valide'

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

Celui-ci ici:

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

semble être très inefficace et coûteux pour les grandes chaînes.

Mieux faire

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)

Un objet tampon conserve une référence à la chaîne d'origine et aux attributs de début et de longueur. De cette façon, aucune duplication inutile des données ne se produit.

Une chaîne de longueur l a l*l/2 sous-chaînes de longueur moyenne l/2; la consommation de mémoire serait donc approximativement l*l*l/4. Avec un tampon, c'est beaucoup plus petit.

Notez que buffer() n'existe que dans la version 2.x. 3.x a memoryview(), qui est utilisé légèrement différent.

Encore mieux serait de calculer les index et de découper la sous-chaîne à la demande.

17
glglgl

Si vous obtenez une MemoryError inattendue et que vous pensez que vous devriez avoir beaucoup de RAM disponible, c'est peut-être parce que vous utilisez une installation python 32 bits. 

La solution simple, si vous avez un système d'exploitation 64 bits, consiste à passer à une installation de python 64 bits.

Le problème est que le python 32 bits n'a accès qu'à environ 4 Go de RAM. Cela peut diminuer encore davantage si votre système d'exploitation est 32 bits, en raison de la charge de votre système d'exploitation. 

Pour en savoir plus sur les raisons pour lesquelles les systèmes d'exploitation 32 bits sont limités à environ 4 Go de RAM, cliquez ici: https://superuser.com/questions/372881/is-there-a-technical-reason-why- 32-bit-windows-is-limite-à-4gb-of-ram

19
mgoldwasser

A erreur de mémoire signifie que votre programme est à court de mémoire. Cela signifie que votre programme crée en quelque sorte trop d'objets.

Dans votre exemple, vous devez rechercher des parties de votre algorithme susceptibles de consommer beaucoup de mémoire. Je soupçonne que votre programme reçoit de très longues chaînes comme entrées. Par conséquent, s[i:j+1] pourrait être le coupable, car il crée une nouvelle liste. Cependant, la première fois que vous l'utilisez, ce n'est pas nécessaire car vous n'utilisez pas la liste créée. Vous pouvez essayer de voir si ce qui suit aide:

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

Pour remplacer la deuxième création de liste, vous devez absolument utiliser un objet buffer , comme suggéré par glglgl .

Notez également que puisque vous utilisez if j >= i:, vous n'avez pas besoin de démarrer votre xrange à 0. Vous pouvez avoir:

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

Une alternative plus radicale serait d'essayer de retravailler votre algorithme afin de ne pas pré-calculer toutes les sous-chaînes possibles. Au lieu de cela, vous pouvez simplement calculer la sous-chaîne demandée.

6
Rodrigue

L'utilisation de Python 64 bits résout beaucoup de problèmes.

1
Rajeev Kallur