Apariencia
📙 Clase 21 — CSV: tablas para Excel
Fase 4 · Archivos y el mundo exterior ⬅️ Volver al índice de clases
🎯 Qué aprendí
- Leer y escribir CSV (valores separados por comas): el formato de las tablas.
DictWriter/DictReader: CSV ↔ lista de diccionarios, directo.- El botón "Exportar a Excel" de tu app, resuelto.
📖 PARTE TEÓRICA
📊 1. ¿Qué es un CSV?
Texto plano donde cada línea es una fila y las columnas van separadas por comas. Excel, Google Sheets y cualquier sistema lo abren directo.
csv
nombre,tel
Ana,999-111
Luis,988-222| JSON | CSV | |
|---|---|---|
| Forma | estructuras anidadas | tabla plana (filas × columnas) |
| Lo abre un humano en | editor de texto | Excel / Sheets |
| Ideal para | config, datos de la app | exportar/importar tablas |
✍️ 2. Escribir: DictWriter (desde lista de dicts)
Tu formato de siempre — lista de diccionarios — sale a CSV así:
python
import csv
contactos = [
{"nombre": "Ana", "tel": "999-111"},
{"nombre": "Luis", "tel": "988-222"},
]
with open("contactos.csv", "w", newline="", encoding="utf-8") as f:
writer = csv.DictWriter(f, fieldnames=["nombre", "tel"]) # columnas y su orden
writer.writeheader() # fila de títulos
writer.writerows(contactos) # todas las filas⚠️ El
newline=""al abrir es obligatorio concsv(evita filas en blanco intercaladas en Windows). Es el gotcha #1 del módulo.
📖 3. Leer: DictReader (a lista de dicts)
python
with open("contactos.csv", newline="", encoding="utf-8") as f:
for fila in csv.DictReader(f): # usa la 1ª línea como claves
print(dict(fila))
# {'nombre': 'Ana', 'tel': '999-111'}
# {'nombre': 'Luis', 'tel': '988-222'}⚠️ Todo llega como texto: si guardaste
edad=30, vuelve"30". Convierte al leer:int(fila["edad"]).
🧪 Tip de entrevista: "¿Por qué
DictReader/DictWriteren vez dereader/writer?" → Trabajan con diccionarios (columnas por nombre) en vez de listas (por posición): el código no se rompe si cambia el orden de las columnas.
🖥️ EN TU APP DE ESCRITORIO
El clásico botón "Exportar" — tus datos en manos del usuario, en el formato que su jefe entiende:
python
from tkinter import filedialog # diálogo nativo "Guardar como…"
import csv
class App(ctk.CTk):
def _exportar_csv(self):
ruta = filedialog.asksaveasfilename(
defaultextension=".csv",
filetypes=[("CSV (Excel)", "*.csv")],
)
if not ruta: # el usuario canceló
return
with open(ruta, "w", newline="", encoding="utf-8") as f:
writer = csv.DictWriter(f, fieldnames=["texto", "hecha"])
writer.writeheader()
writer.writerows(self._tareas)
self.status.configure(text=f"✅ Exportado a {ruta}")Y el espejo, "Importar": filedialog.askopenfilename() + DictReader + repintar.
💡 El combo
filedialog+ CSV es de lo más pedido en apps de escritorio reales: reportes para contabilidad, respaldo de datos, migración entre sistemas. Los diálogos los vemos a fondo en la Fase 6.
🗄️ CON BASE DE DATOS (caso de uso)
CSV es el idioma de intercambio de las bases de datos: exportar una tabla para Excel, o importar un CSV que te pasaron hacia tu SQLite:
python
# SELECT → CSV (reporte)
filas = con.execute("SELECT nombre, tel FROM contactos").fetchall()
with open("reporte.csv", "w", newline="", encoding="utf-8") as f:
writer = csv.writer(f)
writer.writerow(["nombre", "tel"]) # cabecera
writer.writerows(filas) # las tuplas de la BD, directo
# CSV → INSERT (importación)
with open("nuevos.csv", newline="", encoding="utf-8") as f:
for fila in csv.DictReader(f):
con.execute("INSERT INTO contactos VALUES (:nombre, :tel)", fila)
con.commit()🗄️ Fíjate:
DictReaderproduce dicts y el INSERT con:nombrelos consume — el puente dict=fila de la Clase 04 une todos los formatos.
🏋️ EJERCICIOS CON SOLUCIÓN
Ejercicio 1 — Exportar gastos
Guarda en gastos.csv esta lista, con cabecera: [{"concepto": "luz", "monto": 120}, {"concepto": "agua", "monto": 45}]
Ver solución
python
import csv
gastos = [{"concepto": "luz", "monto": 120}, {"concepto": "agua", "monto": 45}]
with open("gastos.csv", "w", newline="", encoding="utf-8") as f:
writer = csv.DictWriter(f, fieldnames=["concepto", "monto"])
writer.writeheader()
writer.writerows(gastos)Ejercicio 2 — Leer y sumar
Lee gastos.csv y calcula el total (ojo: los montos llegan como texto).
Ver solución
python
import csv
with open("gastos.csv", newline="", encoding="utf-8") as f:
total = sum(int(fila["monto"]) for fila in csv.DictReader(f))
print(total) # 165 ← int() porque CSV entrega stringsEjercicio 3 — Filtrar al importar
Lee gastos.csv y quédate solo con los gastos mayores a 100 (lista de dicts).
Ver solución
python
import csv
with open("gastos.csv", newline="", encoding="utf-8") as f:
grandes = [dict(fila) for fila in csv.DictReader(f) if int(fila["monto"]) > 100]
print(grandes) # [{'concepto': 'luz', 'monto': '120'}]❓ Preguntas y respuestas (autoevaluación)
1. ¿Cuándo CSV y cuándo JSON?
CSV para tablas planas que abrirá Excel/otro sistema; JSON para estructuras anidadas y datos internos de la app.
2. ¿Qué parámetro es obligatorio al abrir archivos para csv y por qué?
newline=""— sin él pueden aparecer filas en blanco intercaladas (especialmente en Windows).
3. ¿De qué tipo llegan los valores al leer un CSV?
Todos string: hay que convertir (
int(),float()) al leer.
4. ¿Qué ventaja da DictWriter sobre writer?
Columnas por nombre (dicts): el orden no importa y el código es autoexplicativo.
📎 Apuntes relacionados
- La lista de dicts de siempre → Clase 04
newline,encodingywith→ Clase 19 · Archivos
➡️ Siguiente
Clase 22 · Librería estándar — datetime, pathlib y random: las pilas incluidas.