HOWTO · Python

Cómo leer líneas específicas de un archivo en Python

Incluye varios métodos para leer líneas concretas de un archivo: `readlines()` para archivos pequeños, `enumerate()` para recorrer archivos grandes y `linecache` para acceder repetidamente a líneas del mismo archivo. `linecache` guarda datos en caché, por lo que puede usar memoria.

En esta página

Para leer una o varias líneas concretas de un archivo de texto en Python, decide primero si el número de línea viene de una persona o del código. Las personas suelen contar las líneas desde 1, mientras que los índices de las listas empiezan en 0. Para un archivo pequeño, readlines() carga todas las líneas para acceder a ellas por índice. En un archivo grande, enumerate() permite recorrerlas progresivamente. Si necesitas consultar líneas varias veces, linecache ofrece acceso por número de línea y guarda datos en caché, así que no mantiene un uso de memoria constante.

Elige primero una convención para numerar las líneas

Si alguien pide la línea 3, el índice correspondiente en una lista es 3 - 1, es decir, 2. De forma predeterminada, enumerate() también empieza con el índice 0. En cambio, linecache.getline(path, 3) espera el número de línea habitual para una persona: 3. Mantener claras estas convenciones evita errores de desfase de una posición. Las líneas de texto suelen incluir el salto de línea final; quítalo solo si vas a mostrar o comparar el valor sin ese espacio en blanco.

Lee líneas concretas de un archivo pequeño con readlines()

readlines() devuelve una lista con todas las líneas, incluido el salto de línea cuando lo hay. Es práctico si el archivo cabe cómodamente en la memoria y necesitas acceder a varias posiciones. El siguiente ejemplo autónomo crea un archivo de texto temporal e imprime su tercera línea:

El código y las etiquetas o salidas visibles de esta sección se mantienen en inglés.

from pathlib import Path
from tempfile import TemporaryDirectory

with TemporaryDirectory() as folder:
    path = Path(folder) / "notes.txt"
    path.write_text("first\nsecond\nthird\nfourth\n", encoding="utf-8")
    with path.open(encoding="utf-8") as file:
        lines = file.readlines()
    print(lines[2].rstrip("\n"))

Para obtener un rango de números de línea habituales, desde first_line hasta last_line inclusive, usa el segmento lines[first_line - 1:last_line]. El extremo final del segmento no se incluye; por eso el propio número de la última línea sirve como índice final. Si la línea solicitada podría no existir, comprueba que el índice esté dentro de len(lines) antes de acceder a la lista.

Lee líneas concretas de un archivo grande con enumerate()

Recorrer el archivo directamente evita crear una lista con todas sus líneas. enumerate(file) proporciona un índice desde 0 a medida que lee cada línea; suma 1 si vas a mostrar un número de línea para una persona. Para llegar a una línea posterior, aun así hay que pasar por las anteriores. Por eso, este método ayuda a reducir el uso de memoria, pero no permite saltar directamente a una línea distante.

El código y las etiquetas o salidas visibles de esta sección se mantienen en inglés.

from pathlib import Path
from tempfile import TemporaryDirectory

with TemporaryDirectory() as folder:
    path = Path(folder) / "events.txt"
    path.write_text("start\nready\nconnected\nfinished\n", encoding="utf-8")
    wanted = {2, 4}
    with path.open(encoding="utf-8") as file:
        for line_number, line in enumerate(file, start=1):
            if line_number in wanted:
                print(line_number, line.rstrip("\n"))
            if line_number >= max(wanted):
                break

Aquí, start=1 hace que la variable del bucle represente el número de línea habitual para una persona, lo que puede facilitar la lectura de las condiciones de selección. Si el archivo tiene menos líneas de las solicitadas, el bucle simplemente termina sin imprimir las que no existen.

Usa linecache para acceder repetidamente a líneas

Usa linecache.getline(path, line_number) cuando el código necesite consultar varias veces líneas indicando su número, que empieza en 1. Devuelve la línea como texto, incluido el salto de línea cuando lo hay. Si la línea no existe, devuelve una cadena vacía. linecache guarda el contenido del archivo en caché para volver a utilizarlo; esto puede resultar práctico al consultar varias veces el mismo archivo, pero los datos almacenados siguen ocupando memoria.

El código y las etiquetas o salidas visibles de esta sección se mantienen en inglés.

import linecache
from pathlib import Path
from tempfile import TemporaryDirectory

with TemporaryDirectory() as folder:
    path = Path(folder) / "report.txt"
    path.write_text("header\nalpha\nbeta\n", encoding="utf-8")
    line = linecache.getline(str(path), 2)
    print(line.rstrip("\n"))
    linecache.clearcache()

La llamada explícita a clearcache() libera las entradas almacenadas en caché al terminar este ejemplo. Si el archivo cambia, hay que tener en cuenta la vigencia de la caché: vacíala antes de volver a solicitar líneas cuando el programa haya modificado el archivo y necesite descartar los datos guardados.

Gestiona rangos, líneas inexistentes y límites de memoria

Elige readlines() cuando el acceso directo a un archivo manejable sea más importante que evitar cargar su contenido en memoria. Elige enumerate() para procesar un archivo grande progresivamente o detenerte en una línea concreta; para llegar a una línea posterior, tendrás que leer las anteriores. Elige linecache para consultar varias veces líneas por número si te resulta aceptable mantener su caché. Ninguno de estos métodos puede obtener una línea que esté después del final del archivo: el acceso a la lista genera IndexError, la iteración no encuentra coincidencias y getline() devuelve una cadena vacía. Valida la solicitud o gestiona ese resultado según las necesidades del programa.

Abre los archivos de texto en modo de lectura y, preferiblemente, con una instrucción with para que se cierren al terminar el bloque. Especifica una codificación cuando conozcas la del archivo. Cargar el archivo completo puede requerir mucha memoria a medida que aumentan el número y la longitud de las líneas; no hay un límite de tamaño universal que sirva para todos los equipos y usos. La lectura progresiva limita las líneas que conserva el bucle, aunque las líneas seleccionadas que guardes seguirán ocupando memoria. Para elegir, conviene guiarse por el patrón de acceso y la memoria disponible, en vez de por afirmaciones generales sobre tamaño o velocidad.