Archivos CSV en Python: leer, escribir y procesar datos

Publicado el: 11/07/2026
Tempo de leitura: 4 minutos
Leitura e escrita de arquivos CSV em Python

Los archivos CSV siguen siendo uno de los formatos más utilizados para intercambiar datos entre hojas de cálculo, sistemas administrativos, bases de datos y scripts. Su apariencia simple puede engañar: separadores distintos, comillas, saltos de línea, codificaciones y columnas incompletas pueden provocar errores difíciles de detectar. Python incluye el módulo csv, que permite leer y escribir estos archivos sin depender de librerías externas.

Para ampliar el tema puedes consultar la guía de archivos de texto en Python, el tutorial de Pandas para principiantes, la introducción a diccionarios, el manejo de excepciones y la explicación de bucles for.

Las fuentes externas recomendadas son la documentación oficial del módulo csv y el RFC 4180 sobre el formato CSV. Aunque existen variaciones, estas referencias ayudan a entender las reglas de comillas, líneas y separadores.

Qué es realmente un archivo CSV

CSV significa valores separados por comas, pero no todos los archivos utilizan comas. En muchos países se usa punto y coma porque la coma representa decimales. Además, un campo puede contener el propio separador, comillas o saltos de línea. Por eso no conviene dividir cada fila manualmente con split(',').

nombre,ciudad,comentario
Ana,Madrid,"Prefiere correo, no teléfono"

El módulo csv interpreta correctamente las comillas y evita que el comentario se convierta en dos columnas.

Leer un CSV básico

import csv

with open("clientes.csv", "r", encoding="utf-8", newline="") as archivo:
    lector = csv.reader(archivo)
    for fila in lector:
        print(fila)

El parámetro newline="" permite que el módulo controle correctamente los saltos de línea, especialmente en Windows. Define siempre la codificación; UTF-8 es una opción adecuada cuando controlas la generación del archivo.

Ignorar el encabezado

with open("clientes.csv", encoding="utf-8", newline="") as archivo:
    lector = csv.reader(archivo)
    encabezado = next(lector, None)

    for fila in lector:
        print(fila)

next(lector, None) no genera una excepción si el archivo está vacío. Aun así, debes validar que el encabezado tenga las columnas esperadas.

Usar DictReader

DictReader convierte cada registro en un diccionario, lo que hace el código más claro:

with open("clientes.csv", encoding="utf-8", newline="") as archivo:
    lector = csv.DictReader(archivo)

    for cliente in lector:
        print(cliente["nombre"], cliente["ciudad"])

Los nombres se obtienen de la primera fila. Puedes revisar lector.fieldnames y detectar columnas faltantes antes de procesar miles de registros.

requeridas = {"nombre", "email", "ciudad"}
actuales = set(lector.fieldnames or [])
faltantes = requeridas - actuales

if faltantes:
    raise ValueError(f"Faltan columnas: {sorted(faltantes)}")

Trabajar con punto y coma

lector = csv.DictReader(
    archivo,
    delimiter=";",
)

También puedes detectar el dialecto con csv.Sniffer, pero no confíes completamente en una muestra pequeña:

muestra = archivo.read(4096)
archivo.seek(0)

dialecto = csv.Sniffer().sniff(muestra, delimiters=",;\t|")
lector = csv.DictReader(archivo, dialect=dialecto)

En procesos conocidos, es preferible configurar el separador explícitamente.

Convertir tipos

El módulo devuelve texto. Debes convertir números, fechas y booleanos:

from datetime import datetime

cantidad = int(fila["cantidad"])
precio = float(fila["precio"].replace(",", "."))
fecha = datetime.strptime(fila["fecha"], "%Y-%m-%d").date()

La conversión puede fallar. Registra el número de línea para localizar el problema:

for numero_linea, fila in enumerate(lector, start=2):
    try:
        cantidad = int(fila["cantidad"])
    except (TypeError, ValueError):
        print(f"Cantidad inválida en la línea {numero_linea}")

Escribir un CSV

import csv

filas = [
    ["Ana", "[email protected]", "Madrid"],
    ["Luis", "[email protected]", "Lima"],
]

with open("salida.csv", "w", encoding="utf-8", newline="") as archivo:
    escritor = csv.writer(archivo)
    escritor.writerow(["nombre", "email", "ciudad"])
    escritor.writerows(filas)

writerow escribe una fila y writerows recibe un iterable de filas. El módulo añade comillas cuando son necesarias.

Escribir diccionarios con DictWriter

campos = ["nombre", "email", "ciudad"]

with open("salida.csv", "w", encoding="utf-8", newline="") as archivo:
    escritor = csv.DictWriter(archivo, fieldnames=campos)
    escritor.writeheader()
    escritor.writerow({
        "nombre": "Ana",
        "email": "[email protected]",
        "ciudad": "Madrid",
    })

Si el diccionario contiene claves adicionales, configura extrasaction="ignore" solo cuando esa pérdida sea intencional. Normalmente es mejor detectar una estructura inesperada.

Añadir registros sin borrar el archivo

with open("registro.csv", "a", encoding="utf-8", newline="") as archivo:
    escritor = csv.writer(archivo)
    escritor.writerow(["2026-07-11", "Proceso completado"])

Antes de añadir, comprueba si el archivo existe y si ya contiene encabezado. La escritura simultánea desde varios procesos necesita coordinación para evitar datos mezclados.

Procesar archivos grandes

csv.reader trabaja de forma iterativa, por lo que no necesita cargar todo el archivo en memoria:

total = 0.0

with open("ventas.csv", encoding="utf-8", newline="") as archivo:
    lector = csv.DictReader(archivo)
    for fila in lector:
        total += float(fila["total"])

print(total)

Este patrón es adecuado para millones de filas cuando solo necesitas una agregación. Si requieres filtros, uniones o agrupaciones complejas, Pandas puede resultar más cómodo, aunque consumirá más memoria si carga el archivo completo.

Filtrar y transformar registros

with open("ventas.csv", encoding="utf-8", newline="") as entrada, \
     open("ventas_validas.csv", "w", encoding="utf-8", newline="") as salida:

    lector = csv.DictReader(entrada)
    escritor = csv.DictWriter(salida, fieldnames=lector.fieldnames)
    escritor.writeheader()

    for fila in lector:
        try:
            total = float(fila["total"])
        except (TypeError, ValueError):
            continue

        if total >= 100:
            fila["total"] = f"{total:.2f}"
            escritor.writerow(fila)

En un sistema real, guarda los registros rechazados en otro archivo junto con el motivo. Descartarlos silenciosamente dificulta las auditorías.

Evitar fórmulas peligrosas

Cuando un CSV será abierto en Excel o herramientas similares, valores que empiezan con =, +, - o @ pueden interpretarse como fórmulas. Esto se conoce como CSV Injection. Si exportas datos proporcionados por usuarios, valida o neutraliza esos prefijos según las necesidades del sistema.

def seguro_para_hoja(valor):
    texto = str(valor)
    if texto.startswith(("=", "+", "-", "@")):
        return "'" + texto
    return texto

Manejar UTF-8 con BOM

Algunos archivos generados por Excel incluyen una marca BOM. Puedes leerlos con utf-8-sig:

with open("datos.csv", encoding="utf-8-sig", newline="") as archivo:
    lector = csv.DictReader(archivo)

Esto evita que la primera columna aparezca con caracteres invisibles.

Crear una función reutilizable

from pathlib import Path
import csv


def leer_clientes(ruta):
    ruta = Path(ruta)
    if not ruta.is_file():
        raise FileNotFoundError(ruta)

    with ruta.open(encoding="utf-8-sig", newline="") as archivo:
        lector = csv.DictReader(archivo)
        requeridas = {"nombre", "email", "ciudad"}
        faltantes = requeridas - set(lector.fieldnames or [])
        if faltantes:
            raise ValueError(f"Faltan columnas: {faltantes}")

        for numero, fila in enumerate(lector, start=2):
            yield numero, fila

El uso de yield mantiene el procesamiento incremental y facilita informar el número de línea.

Errores frecuentes

Los problemas más habituales son usar split, olvidar newline="", asumir que el separador siempre es coma, no definir la codificación, convertir números sin validar y sobrescribir el archivo original. También es frecuente confiar en que todas las filas tienen la misma cantidad de columnas.

Conclusión

El módulo csv ofrece todo lo necesario para leer, escribir y transformar archivos tabulares de forma eficiente. Utiliza DictReader para un código legible, valida encabezados, convierte tipos de manera explícita y registra filas inválidas. Con estas prácticas puedes automatizar intercambios de datos sin depender de procesos manuales ni introducir errores silenciosos.

Compartilhe:

Facebook
WhatsApp
Twitter
LinkedIn

Contenido del artículo

    Artículos relacionados

    Ilustração que representa um algoritmo
    Fundamentos
    Foto de perfil de Leandro Hirt da Academify

    Qué es un algoritmo en programación: guía con Python

    Entiende qué es un algoritmo, cómo describirlo con pseudocódigo, analizar su complejidad y convertirlo en funciones Python comprobables.

    Ler mais

    Tempo de leitura: 5 minutos
    11/07/2026
    Programador resolvendo problemas com Python
    Fundamentos
    Foto de perfil de Leandro Hirt da Academify

    Lógica de programación con Python para principiantes

    Aprende lógica de programación con Python mediante algoritmos, pseudocódigo, condiciones, bucles, funciones, validación y pruebas.

    Ler mais

    Tempo de leitura: 4 minutos
    11/07/2026
    Ilustração representando conjuntos (sets) em Python
    Fundamentos
    Foto de perfil de Leandro Hirt da Academify

    Sets en Python: guía completa de conjuntos

    Aprende sets en Python: unicidad, pertenencia, unión, intersección, diferencias, frozenset, rendimiento y errores comunes.

    Ler mais

    Tempo de leitura: 4 minutos
    11/07/2026
    texto 'operadores em Python' com os simbolos de operadores e o logo do Python à direita
    Fundamentos
    Foto de perfil de Leandro Hirt da Academify

    Operadores en Python: guía completa con ejemplos

    Aprende operadores aritméticos, lógicos, de comparación, identidad, pertenencia, bits, sets y precedencia en Python.

    Ler mais

    Tempo de leitura: 4 minutos
    11/07/2026
    Símbolo de repetição ao lado do logotipo do Python pensativo, representando o conceito de loops na programação em Python.
    Fundamentos
    Foto de perfil de Leandro Hirt da Academify

    Bucles en Python: for y while explicados con ejemplos

    Aprende bucles for y while en Python con range, enumerate, zip, break, continue, else, comprensiones, generadores y ejemplos prácticos.

    Ler mais

    Tempo de leitura: 5 minutos
    11/07/2026
    ícone de loop com o texto 'While' abaixo
    Fundamentos
    Foto de perfil de Leandro Hirt da Academify

    Bucles while en Python: guía práctica para principiantes

    Aprende bucles while en Python con condiciones, validación, menús, break, continue, else, centinelas, reintentos y buenas prácticas.

    Ler mais

    Tempo de leitura: 5 minutos
    11/07/2026