una txt texto partir lista linea leer importar gestion especifica español ejercicios crear como archivos archivo python file seek

txt - leer una linea especifica de un archivo en python



¿Cuál es la forma más eficiente de obtener la primera y la última línea de un archivo de texto? (11)

¿Puedes usar comandos de Unix? Creo que usar head -1 y tail -n 1 son probablemente los métodos más eficientes. Alternativamente, puede usar una simple fid.readline() para obtener la primera línea y fid.readlines()[-1] , pero puede llevar demasiada memoria.

Tengo un archivo de texto que contiene una marca de tiempo en cada línea. Mi objetivo es encontrar el rango de tiempo. Todos los horarios están en orden, por lo que la primera línea será la más temprana y la última será la última. Solo necesito la primera y última línea. ¿Cuál sería la forma más eficiente de obtener estas líneas en python?

Nota: Estos archivos son de una longitud relativamente grande, de 1 a 2 millones de líneas cada uno y tengo que hacer esto para varios cientos de archivos.


Aquí hay una extensión de la respuesta de @ Trasp que tiene una lógica adicional para manejar el caso de esquina de un archivo que tiene solo una línea. Puede ser útil manejar este caso si en repetidas ocasiones desea leer la última línea de un archivo que se actualiza continuamente. Sin esto, si intenta tomar la última línea de un archivo que acaba de crearse y tiene solo una línea, se IOError: [Errno 22] Invalid argument .

def tail(filepath): with open(filepath, "rb") as f: first = f.readline() # Read the first line. f.seek(-2, 2) # Jump to the second last byte. while f.read(1) != b"/n": # Until EOL is found... try: f.seek(-2, 1) # ...jump back the read byte plus one more. except IOError: f.seek(-1, 1) if f.tell() == 0: break last = f.readline() # Read last line. return last


Aquí hay una versión modificada de la respuesta de SilentGhost que hará lo que quieras.

with open(fname, ''rb'') as fh: first = next(fh) offs = -100 while True: fh.seek(offs, 2) lines = fh.readlines() if len(lines)>1: last = lines[-1] break offs *= 2 print first print last

No hay necesidad de un límite superior para la longitud de línea aquí.


Esta es mi solución, compatible también con Python3. También administra casos de frontera, pero pierde soporte para utf-16:

def tail(filepath): """ @author Marco Sulla ([email protected]) @date May 31, 2016 """ try: filepath.is_file fp = str(filepath) except AttributeError: fp = filepath with open(fp, "rb") as f: size = os.stat(fp).st_size start_pos = 0 if size - 1 < 0 else size - 1 if start_pos != 0: f.seek(start_pos) char = f.read(1) if char == b"/n": start_pos -= 1 f.seek(start_pos) if start_pos == 0: f.seek(start_pos) else: char = "" for pos in range(start_pos, -1, -1): f.seek(pos) char = f.read(1) if char == b"/n": break return f.readline()

Está inspirado por la respuesta de Trasp y el comentario de AnotherParker .


Nadie mencionó usar invertido:

f=open(file,"r") r=reversed(f.readlines()) last_line_of_file = r.next()


Obtener la primera línea es trivialmente fácil. Para la última línea, suponiendo que conoces un límite superior aproximado en la longitud de la línea, os.lseek algún importe de SEEK_END encontrar la penúltima línea y luego readline() la última línea.


Primero abra el archivo en modo de lectura. Luego use el método readlines () para leer línea por línea. Todas las líneas almacenadas en una lista. Ahora puede usar las divisiones de lista para obtener la primera y la última línea del archivo.

a=open(''file.txt'',''rb'') lines = a.readlines() if lines: first_line = lines[:1] last_line = lines[-1]


Puede abrir el archivo para leer y leer la primera línea usando la línea de lectura incorporada readline() , luego buscar hasta el final del archivo y retroceder hasta encontrar el EOL precedente de la línea y leer la última línea desde allí.

with open(file, "rb") as f: first = f.readline() # Read the first line. f.seek(-2, os.SEEK_END) # Jump to the second last byte. while f.read(1) != b"/n": # Until EOL is found... f.seek(-2, os.SEEK_CUR) # ...jump back the read byte plus one more. last = f.readline() # Read last line.

Saltar al segundo último byte en lugar del último impide que regrese directamente debido a un EOL final. Mientras retrocede, también querrá pasar dos bytes, ya que la lectura y la comprobación de EOL empujan la posición un paso adelante.

Cuando se usa seek el formato es seek donde significa el relativo al offset. Cita de seek :

  • seek o seek = buscar desde el inicio de la secuencia (por defecto); offset debe ser un número devuelto por TextIOBase.tell() o cero. Cualquier otro valor de compensación produce un comportamiento indefinido.
  • seek o seek = "buscar" a la posición actual; el desplazamiento debe ser cero, que es una no operación (todos los demás valores no están soportados).
  • seek o seek = buscar hasta el final de la secuencia; el desplazamiento debe ser cero (todos los demás valores no son compatibles).

Ejecutarlo a través del tiempo 10k veces en un archivo con 6k líneas que totalizan 200kB me dio 1.62s vs 6.92s cuando comparé con el for-loop debajo de lo que sugerí anteriormente. Usando un archivo de 1.3GB de tamaño, aún con 6k líneas, cien veces resultó en 8.93 vs 86.95.

with open(file, "rb") as f: first = f.readline() # Read the first line. for last in f: pass # Loop through the whole file reading it all.


documentos para el módulo io

with open(fname, ''rb'') as fh: first = next(fh).decode() fh.seek(-1024, 2) last = fh.readlines()[-1].decode()

El valor de la variable aquí es 1024: representa la longitud promedio de la cadena. Elijo 1024 solo por ejemplo. Si tiene una estimación de longitud de línea promedio, puede usar ese valor multiplicado por 2.

Como no tiene idea alguna sobre el posible límite superior para la longitud de la línea, la solución obvia sería recorrer el archivo:

for line in fh: pass last = line

No necesita molestarse con la bandera binaria que podría usar open(fname) .

ETA : ya que tiene muchos archivos para trabajar, puede crear una muestra de un par de docenas de archivos usando random.sample y ejecutar este código en ellos para determinar la longitud de la última línea. Con un gran valor a priori del cambio de posición (digamos 1 MB). Esto lo ayudará a estimar el valor de la ejecución completa.


w=open(file.txt, ''r'') print (''first line is : '',w.readline()) for line in w: x= line print (''last line is : '',x) w.close()

El bucle for ejecuta a través de las líneas y x obtiene la última línea en la iteración final.


with open("myfile.txt") as f: lines = f.readlines() first_row = lines[0] print first_row last_row = lines[-1] print last_row