Python trae un módulo csv que resuelve las partes difíciles del formato: las comillas dentro de los campos, los separadores dentro de los valores y los saltos de línea. Usarlo cuesta lo mismo que no usarlo.
También te puede interesar
Escribir
import csv
from pathlib import Path
p = Path("datos.csv")
with p.open("w", encoding="utf-8", newline="") as f:
w = csv.DictWriter(f, fieldnames=["nombre", "ciudad", "precio"], delimiter=";")
w.writeheader()
w.writerows(filas)
datos.csvnombre;ciudad;precio "bufanda ""larga""";A Coruña;9.00 "mochila; grande";Madrid;34.00
Mira lo que hizo solo: entrecomilló los dos campos que lo necesitaban y duplicó las comillas de dentro. Eso es el formato CSV bien hecho, y es lo que te ahorras escribir.
newline="" no es opcional. El módulo csv gestiona él mismo los finales de línea; sin ese argumento, en Windows salen líneas en blanco entre registro y registro. Hay que ponerlo siempre, al abrir tanto para leer como para escribir.Leer
with p.open(encoding="utf-8", newline="") as f:
for fila in csv.DictReader(f, delimiter=";"):
print(fila["nombre"], fila["ciudad"], float(fila["precio"]))
salidabufanda "larga" A Coruña 9.00 mochila; grande Madrid 34.00
Volvieron enteros, con las comillas deshechas y el punto y coma de «mochila; grande» intacto. DictReader usa la primera fila como nombres de columna, lo que se lee mucho mejor que fila[2] y aguanta que cambien de orden.
Y ojo con una cosa: todo llega como cadena. El float() lo pones tú; el módulo no adivina tipos.
Por qué nunca split
linea = '"mochila; grande";Madrid;34.00'
salidasplit(';') -> ['"mochila', ' grande"', 'Madrid', '34.00']
csv.reader -> ['mochila; grande', 'Madrid', '34.00']
Cuatro campos en vez de tres, y todas las columnas desplazadas a partir de ahí. Si el archivo viene de fuera, antes o después hay un campo con el separador dentro.
Cuando no sabes el separador
d = csv.Sniffer().sniff(muestra, delimiters=",;\t") csv.Sniffer().has_header(muestra)
salidaSniffer dice: ';' ¿hay cabecera? True
Útil para archivos ajenos, donde nunca sabes si vienen con coma, con punto y coma —lo habitual en España, porque la coma es el decimal— o con tabulador. No es infalible: dale varios cientos de bytes de muestra, no una línea.
Saltos de línea dentro de un campo
salidaescrito: 'nota;"línea 1\nlínea 2"\r\n' leído : ['nota', 'línea 1\nlínea 2']
Esto es lo que rompe a los analizadores caseros, incluidos los que leen línea a línea: un registro puede ocupar varias líneas del archivo. El módulo csv lo lleva bien, y por eso hay que iterar el lector y no el archivo.
| Para… | Usa |
|---|---|
| Leer con nombres de columna | csv.DictReader |
| Escribir desde diccionarios | csv.DictWriter + writeheader() |
| Listas en vez de diccionarios | csv.reader / csv.writer |
| Separador europeo | delimiter=";" |
| Adivinar el formato | csv.Sniffer() |
| Evitar líneas en blanco | newline="" al abrir |
| Archivos enormes o cálculo | pandas o polars, no csv |
Todo el código se ejecutó con Python 3.14 en un contenedor limpio antes de publicar esta página; las salidas están copiadas de esa ejecución.