Tablas como texto
Un archivo CSV (valores separados por comas) guarda una tabla como texto: una fila por línea, celdas separadas por comas, normalmente con una fila de encabezado que nombra las columnas. Los históricos de precios, los libros de operaciones y las exportaciones de casi cualquier herramienta tienen este formato. Parece fácil de analizar con line.split(","), pero una celda puede contener una coma, y entonces va entre comillas: AAPL,"Q3, adjusted". Dividir a mano falla ahí, así que usa el módulo estándar csv y abre el archivo con newline="" para que los saltos de línea dentro de las celdas se traten bien.
import csv
# Write a small table with csv.writer
with open("prices.csv", "w", newline="", encoding="utf-8") as file:
writer = csv.writer(file)
writer.writerow(["date", "symbol", "close", "note"])
writer.writerow(["2025-01-02", "AAPL", 184.25, "Q3, adjusted"])
writer.writerow(["2025-01-03", "AAPL", 185.5, ""])
# The comma inside the note is quoted for us
with open("prices.csv", encoding="utf-8") as file:
print(file.read().splitlines()[1]) # 2025-01-02,AAPL,184.25,"Q3, adjusted"Leer filas
csv.reader(file) produce cada fila como una lista de cadenas. csv.DictReader(file) lee primero el encabezado y luego produce cada fila como un diccionario con los nombres de columna como claves, más legible y a salvo de que cambie el orden de las columnas. En ambos casos cada celda es texto: convierte con float(...) o int(...) antes de operar. Pasa delimiter=";" (o "\t") para archivos con otro separador.
import csv
# DictReader gives each row as a dict; cells are strings
closes = []
with open("prices.csv", newline="", encoding="utf-8") as file:
for row in csv.DictReader(file):
closes.append(float(row["close"]))
print(closes) # [184.25, 185.5]
# csv.reader gives plain lists, header included
with open("prices.csv", newline="", encoding="utf-8") as file:
rows = list(csv.reader(file))
print(rows[0]) # ['date', 'symbol', 'close', 'note']
print(rows[1]) # ['2025-01-02', 'AAPL', '184.25', 'Q3, adjusted']Escribir filas
csv.writer(file).writerow(values) escribe una fila y pone comillas cuando hace falta; los números se convierten a texto por ti. csv.DictWriter(file, fieldnames=[...]) escribe diccionarios y writeheader() escribe primero los nombres de columna. Abre el archivo con "w" y newline=""; sin newline="", Windows puede dejar líneas en blanco entre filas.
import csv
# DictWriter: header first, then one dict per row
trades = [{"symbol": "AAPL", "quantity": 200}, {"symbol": "MSFT", "quantity": 50}]
with open("trades.csv", "w", newline="", encoding="utf-8") as file:
writer = csv.DictWriter(file, fieldnames=["symbol", "quantity"])
writer.writeheader()
writer.writerows(trades)
with open("trades.csv", encoding="utf-8") as file:
print(file.read().splitlines()) # ['symbol,quantity', 'AAPL,200', 'MSFT,50']import csv
# Cells are text until you convert them
with open("prices.csv", newline="", encoding="utf-8") as file:
row = next(csv.DictReader(file))
print(repr(row["close"]), row["close"] * 2) # '184.25' 184.25184.25
print(float(row["close"]) * 2) # 368.5
# Another separator: semicolons
with open("euro.csv", "w", newline="", encoding="utf-8") as file:
csv.writer(file, delimiter=";").writerow(["AAPL", "184,25"])
with open("euro.csv", newline="", encoding="utf-8") as file:
print(next(csv.reader(file, delimiter=";"))) # ['AAPL', '184,25']184.25, 200 y AAPL son solo caracteres hasta que los conviertes. Olvidarlo da "184.25" * 200 (el texto repetido 200 veces) en lugar de un error. Convierte cada columna una vez, justo donde la lees, y comprueba los nombres del encabezado en vez de suponer posiciones.- Abre con
newline=""; no dividas ni unas líneas CSV a mano. csv.DictReaderlee filas como diccionarios; cada celda es una cadena.csv.writer/csv.DictWriterescriben filas y ponen las comillas por ti.
A continuación: datos JSON, para registros anidados que no caben en una tabla plana.
Lab: qué se califica
- Agrupar los cierres por símbolo con
read_closes25 pts - Guardar operaciones como CSV con
write_trades25 pts - Totalizar el valor negociado por símbolo con
total_by_symbol25 pts - Copiar las filas de un símbolo a un archivo nuevo con
filter_rows25 pts