Leer líneas específicas de un archivo en un bucle (optimización)

Estoy leyendo líneas específicas de un archivo de texto. Aquí está mi código:

file.seek(0)
for j, ln in enumerate(file):
   if j == line_number
      line = ln   # i'm getting the line
      break

tomó un largo tiempo cuando uso este código en un "bucle" donde el line_number es aleatorio en cada turno. También probé linecache.getline() pero debe llamarse linecache.clearcache() cada turno, por lo que no es mejor.

¿Hay una solución más rápida para eso? La memoria no importa.

preguntado el 03 de mayo de 12 a las 22:05

4 Respuestas

Si la memoria realmente no importa:

lines = file.readlines()

line = lines[line_number]

Usted lee el archivo una vez, lo almacena en la memoria y accede a él desde allí.

Editar: Donde la memoria importa:

from itertools import dropwhile

line = next(dropwhile(lambda x: x[0]==line_number, enumerate(file)))[1]

Podemos utilizar itertools.dropwhile() para ignorar las líneas hasta llegar a la que necesitamos.

contestado el 03 de mayo de 12 a las 22:05

usa esto arriba del bucle:

with open('in.txt') as f:
 lines=[ln for ln in f]

ahora acceda a cualquier número de línea dentro del ciclo:

lines[line_number]

contestado el 03 de mayo de 12 a las 22:05

¿Por qué has usado rstrip()? El autor de la pregunta no mencionó la necesidad de hacer eso. - gareth latty

@Hern for-in loop es mucho más eficiente en memoria que readlines() , se accederá al archivo solo una vez. - Ashwini Chaudhary

@AshwiniChaudhary ¿Qué? ¿Por qué es esto más eficiente que readlines()? - gareth latty

readlines() lee un archivo completo a la vez, por lo que en el caso de un archivo enorme, este método se vuelve ineficiente para la memoria. Pero para archivos pequeños readlines() es mucho más rápido que readline(). - Ashwini Chaudhary

@AshwiniChaudhary Excepto en su caso, puede estar leyendo línea por línea, pero luego está construyendo una lista a partir de ella. Si readlines() usa demasiada memoria al hacer una lista de todas las líneas, luego hacer una lista manualmente también lo hará. Su declaración solo se aplica si está trabajando en cada línea y luego desecha esa línea. - gareth latty

def getLine(fileObj, lineNo):
    [fileObj.readline() for i in xrange(lineNo - 1)]
    return fileObj.readline()

contestado el 03 de mayo de 12 a las 22:05

Otra forma de hacer

import linecache
linecache.getline('myfile', line_number)

Respondido el 25 de enero de 13 a las 08:01

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.