Cómo resolver el error de memoria en Python

Estoy tratando con varios archivos de texto grande, cada uno de ellos tiene aproximadamente 8000000 líneas. Un breve ejemplo de las líneas son:

usedfor zipper fasten_coat usedfor zipper fasten_jacket usedfor zipper fasten_pant usedfor your_foot walk atlocation camera cupboard atlocation camera drawer atlocation camera house relatedto more plenty 

El código para almacenarlos en un diccionario es:

 dicCSK = collections.defaultdict(list) for line in finCSK: line=line.strip('\n') try: r, c1, c2 = line.split(" ") except ValueError: print line dicCSK[c1].append(r+" "+c2) 

Funciona bien en el primer archivo txt, pero cuando se ejecuta en el segundo archivo txt, recibí un error MemoryError .

Estoy usando la ventana 7 de 64 bits con python 2.7 de 32 bits, Intel i5 cpu, con memoria de 8Gb. ¿Cómo puedo solucionar el problema?

Explicación adicional: tengo cuatro archivos grandes, cada archivo contiene información diferente para muchas entidades. Por ejemplo, quiero encontrar toda la información para el cat , su animal nodo padre y su persian cat nodo hijo y así sucesivamente. Entonces mi progtwig primero leyó todos los archivos de texto en el diccionario, luego escaneo todos los diccionarios para encontrar información sobre cat y su padre y sus hijos.

La solución más sencilla: probablemente se esté quedando sin espacio de direcciones virtuales (cualquier otra forma de error generalmente significa que se ejecuta muy lentamente durante mucho tiempo antes de que finalmente obtenga un MemoryError ). Esto se debe a que una aplicación de 32 bits en Windows (y en la mayoría de los sistemas operativos) está limitada a 2 GB de espacio de direcciones de modo de usuario (se puede modificar Windows para que sea de 3 GB, pero eso sigue siendo un límite bajo). Tienes 8 GB de RAM, pero tu progtwig no puede usar (al menos) 3/4 de ella. Python tiene una buena cantidad de sobrecarga por objeto (encabezado de objeto, alineación de asignación, etc.), las probabilidades son solo las cadenas que se están utilizando cerca de un GB de RAM, y eso es antes de tratar la sobrecarga del diccionario, el rest de su progtwig, el rest de Python, etc. Si los fragmentos de espacio de memoria son suficientes y el diccionario necesita crecer, es posible que no tenga suficiente espacio contiguo para reasignar, y obtendrá un MemoryError .

Instala una versión de Python de 64 bits (si puedes, recomiendo actualizar a Python 3 por otras razones); usará más memoria, pero luego tendrá acceso a mucho más espacio de memoria (y también más memoria RAM física).

Si eso no es suficiente, considere la posibilidad de convertir a una base de datos sqlite3 (o algún otro DB), por lo que, naturalmente, se dertwig en el disco cuando los datos se vuelven demasiado grandes para la memoria principal, mientras que todavía tiene una búsqueda bastante eficiente.

Suponiendo que su texto de ejemplo sea representativo de todo el texto, una línea consumiría unos 75 bytes en mi máquina:

 In [3]: sys.getsizeof('usedfor zipper fasten_coat') Out[3]: 75 

Haciendo algunos cálculos aproximados:

 75 bytes * 8,000,000 lines / 1024 / 1024 = ~572 MB 

Entonces, aproximadamente 572 megas para almacenar las cadenas solo para uno de estos archivos. Una vez que comience a agregar archivos adicionales, de estructura similar y tamaño, se acercará rápidamente a sus límites de espacio de direcciones virtuales, como se menciona en la respuesta de @ ShadowRanger.

Si actualizar su Python no es factible para usted, o si solo desplaza la lata por el camino (después de todo, tiene una memoria física finita), realmente tiene dos opciones: escribir sus resultados en archivos temporales entre la carga y la lectura Los archivos de entrada, o escribir sus resultados en una base de datos. Ya que necesita un procesamiento posterior de las cadenas después de agregarlas, escribir en una base de datos sería el mejor enfoque.