HOWTO · Python
Leer la última línea de archivo usando Python
Podemos usar el bucle for y la función file.readlines() para leer la última línea de un archivo en Python.
En esta página
Para obtener la última línea en Python, recorre el archivo y conserva la línea más reciente. Así se lee desde el principio hasta el final, pero solo se guarda una línea a la vez. Si el archivo es muy grande y recorrerlo por completo resulta demasiado lento, puedes leerlo hacia atrás en bloques binarios.
Ejecuta este ejemplo:
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 directory:
path = Path(directory) / "sample.txt"
path.write_text("alpha\nbeta\ngamma\n", encoding="utf-8")
last_line = None
with path.open("r", encoding="utf-8") as file:
for line in file:
last_line = line.rstrip("\r\n")
print(last_line)
gamma
Leer la última línea de un archivo en Python
Los objetos de archivo de Python no ofrecen una operación directa para obtener la «última línea». Leer línea por línea es sencillo y requiere poca memoria adicional, pero aun así hay que llegar al final del archivo. Si el archivo cabe cómodamente en la memoria, readlines() requiere menos código; para archivos grandes, una lectura binaria hacia atrás puede evitar leer el contenido anterior. La mejor opción depende de si priorizas la sencillez, el uso de memoria o evitar recorrer todo el archivo.
Leer línea por línea con un bucle for
Guarda en una variable la línea leída más recientemente. Inicializarla con None proporciona un resultado definido cuando el archivo no contiene líneas. rstrip("\r\n") elimina únicamente los caracteres de fin de línea, por lo que conserva los espacios que formen parte del contenido.
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 directory:
path = Path(directory) / "sample.txt"
path.write_text("first\nsecond\n", encoding="utf-8")
last_line = None
with path.open("r", encoding="utf-8") as file:
for line in file:
last_line = line.rstrip("\r\n")
print(last_line)
El bucle lee todas las líneas, así que el tiempo necesario aumenta con el tamaño del archivo. La memoria adicional se limita a la línea actual y al resultado guardado. Un salto de línea al final no genera una línea extra en el iterador de texto de Python; si dos caracteres de salto de línea representan una última línea vacía, se devuelve como una cadena vacía.
Usar readlines() con archivos pequeños
readlines() devuelve todas las líneas en una lista, por lo que es fácil seleccionar la última. Comprueba que la lista no esté vacía antes de acceder a un elemento: un archivo sin contenido produce una lista vacía. En modo texto, cada cadena devuelta conserva su terminador de línea; si quieres obtener el contenido sin ese terminador, elimina solo \r y \n.
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 directory:
path = Path(directory) / "sample.txt"
path.write_text("first\nsecond\n", encoding="utf-8")
with path.open("r", encoding="utf-8") as file:
lines = file.readlines()
last_line = lines[-1].rstrip("\r\n") if lines else None
print(last_line)
Este método también recorre el archivo completo y guarda todas sus líneas en memoria. Úsalo si necesitas la lista para otra tarea o si el archivo no es muy grande; evita strip() cuando los espacios iniciales o finales puedan ser importantes.
Conservar solo la última línea con deque
Una deque con maxlen=1 descarta los elementos anteriores a medida que llegan líneas nuevas. Recorre el archivo secuencialmente y usa poca memoria, igual que el bucle, pero requiere menos control explícito. Comprueba el resultado antes de llamar a pop() para que la función también pueda manejar un archivo sin líneas.
El código y las etiquetas o salidas visibles de esta sección se mantienen en inglés.
from collections import deque
from pathlib import Path
from tempfile import TemporaryDirectory
with TemporaryDirectory() as directory:
path = Path(directory) / "sample.txt"
path.write_text("first\nsecond\n", encoding="utf-8")
with path.open("r", encoding="utf-8") as file:
lines = deque(file, maxlen=1)
last_line = lines.pop().rstrip("\r\n") if lines else None
print(last_line)
deque limita las líneas que conserva, no la cantidad de datos que lee: también llega hasta el final del archivo. Es útil cuando quieres guardar solo el elemento más reciente mientras lees un archivo como flujo.
Leer hacia atrás desde el final con seek()
Para un archivo grande, abrirlo en modo binario permite usar seek() para desplazarse de forma segura a posiciones expresadas en bytes. La función siguiente comienza al final, quita el salto de línea final si lo hay y después busca hacia atrás, en bloques de tamaño fijo, el salto de línea anterior. Une únicamente los bloques que forman parte de la última línea; por eso, la memoria necesaria depende de la longitud de esa línea y no del archivo completo. Admite finales de línea LF y CRLF, y decodifica los bytes seleccionados con la codificación indicada.
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
def read_last_line(path, encoding="utf-8", chunk_size=8192):
if chunk_size <= 0:
raise ValueError("chunk_size must be positive")
with open(path, "rb") as file:
file.seek(0, 2)
end = file.tell()
if end == 0:
return None
file.seek(end - 1)
position = end - 1 if file.read(1) == b"\n" else end
chunks = []
while position > 0:
start = max(0, position - chunk_size)
file.seek(start)
chunk = file.read(position - start)
newline = chunk.rfind(b"\n")
if newline >= 0:
chunks.append(chunk[newline + 1:])
line = b"".join(reversed(chunks))
return (line[:-1] if line.endswith(b"\r") else line).decode(encoding)
chunks.append(chunk)
position = start
line = b"".join(reversed(chunks))
return (line[:-1] if line.endswith(b"\r") else line).decode(encoding)
with TemporaryDirectory() as directory:
path = Path(directory) / "sample.txt"
path.write_bytes("first\r\nlast line\r\n".encode("utf-8"))
print(read_last_line(path))
Si una línea es más larga que un bloque, se acumulan bloques hasta encontrar su delimitador; si el archivo contiene una sola línea, la lectura retrocede hasta el principio. La línea seleccionada debe ser válida en la codificación especificada. Esta implementación reconoce LF y CRLF como delimitadores, pero no los archivos que usan CR sin LF como separador de líneas. Para codificaciones o convenciones de salto de línea poco habituales, usa un lector de texto secuencial o adapta el tratamiento de los delimitadores.
Usar tail en sistemas tipo Unix
En los sistemas que lo incluyen, el comando externo tail puede devolver la última línea sin que tengas que implementar una lectura hacia atrás. Desde Python, captura los bytes con subprocess.run(["tail", "-n", "1", path], capture_output=True, check=True) y luego decodifica result.stdout con la codificación del archivo. Este método depende de que tail esté instalado y disponible en PATH, y no es una solución nativa de Windows. Pasa una lista de argumentos en lugar de construir un comando de shell a partir de una ruta. El comportamiento y la velocidad del comando dependen del sistema operativo y del archivo.
Elegir un método y tratar los casos límite
| Método | ¿Lee todo el archivo? | Memoria adicional | Úsalo cuando… |
|---|---|---|---|
Bucle for |
Sí | Una línea | Busques un código de lectura secuencial sencillo. |
readlines() |
Sí | Todas las líneas | El archivo sea pequeño o necesites la lista. |
deque con maxlen=1 |
Sí | Una línea | Quieras conservar el estado de lectura de forma concisa. |
Bloques binarios hacia atrás con seek() |
Por lo general, no; puede llegar al principio si la última línea es larga | La última línea y un bloque | El archivo sea grande y use LF o CRLF. |
tail |
Depende de la implementación | Un proceso externo | El sistema de destino proporcione el comando. |
Para un archivo vacío, devuelve None u otro valor centinela documentado en vez de indexar o extraer un elemento sin comprobar antes el resultado. Decide si quieres conservar el terminador de línea; si no, elimina solo \r y \n. El bucle y deque usan poca memoria, pero recorren todo el archivo. readlines() es la opción basada en listas más sencilla para archivos pequeños. Usa la lectura hacia atrás con seek() cuando sea útil evitar leer el contenido anterior y las suposiciones sobre codificación y saltos de línea sean compatibles con el archivo. Elige tail si puedes depender de una utilidad externa disponible en sistemas tipo Unix.