Saltar a contenido

FICHEROS CSV

Introducción

CSV (Comma-Separated Values) es un formato de texto plano para almacenar datos tabulares: filas y columnas. Cada línea representa una fila y los valores de cada columna se separan por un delimitador (habitualmente una coma , o un punto y coma ;).

Ejemplo de fichero alumnos.csv:

nombre,ciclo,nota
Ana García,DAW,8.5
Carlos López,DAM,6.0
María Fernández,DAW,9.2
Pedro Martín,ASIR,5.5

CSV es ideal para:

  • Intercambiar datos con hojas de cálculo (Excel, LibreOffice Calc)
  • Exportar e importar datos de bases de datos
  • Almacenar listados simples sin estructura anidada

Cuando los datos tienen estructura compleja (listas dentro de registros, objetos anidados), JSON es más adecuado que CSV.

El módulo csv

Python incluye el módulo csv en la biblioteca estándar. Nunca debes parsear CSV manualmente con split(","): el módulo gestiona correctamente los casos complejos (campos con comas dentro de comillas, saltos de línea en campos, etc.).

import csv

Lectura con csv.reader

csv.reader itera sobre las filas del fichero, devolviendo cada fila como una lista de strings:

1
2
3
4
5
6
import csv

with open("alumnos.csv", "r", encoding="utf-8", newline="") as f:
    lector = csv.reader(f)
    for fila in lector:
        print(fila)
['nombre', 'ciclo', 'nota']
['Ana García', 'DAW', '8.5']
['Carlos López', 'DAM', '6.0']
['María Fernández', 'DAW', '9.2']
['Pedro Martín', 'ASIR', '5.5']

El parámetro newline="" al abrir el fichero es obligatorio cuando se usa el módulo csv. Sin él, en Windows los saltos de línea se pueden duplicar.

Para saltar la fila de cabecera, usa next():

1
2
3
4
5
6
7
8
import csv

with open("alumnos.csv", "r", encoding="utf-8", newline="") as f:
    lector = csv.reader(f)
    next(lector)   # Salta la cabecera
    for fila in lector:
        nombre, ciclo, nota = fila
        print(f"{nombre} ({ciclo}): {nota}")
Ana García (DAW): 8.5
Carlos López (DAM): 6.0
María Fernández (DAW): 9.2
Pedro Martín (ASIR): 5.5

Lectura con csv.DictReader

csv.DictReader lee el fichero usando la primera fila como cabecera y devuelve cada fila como un diccionario, lo que hace el código más legible:

1
2
3
4
5
6
import csv

with open("alumnos.csv", "r", encoding="utf-8", newline="") as f:
    lector = csv.DictReader(f)
    for fila in lector:
        print(fila["nombre"], fila["ciclo"], fila["nota"])
Ana García DAW 8.5
Carlos López DAM 6.0
María Fernández DAW 9.2
Pedro Martín ASIR 5.5

DictReader es la opción recomendada cuando el CSV tiene cabeceras, ya que acceder a los campos por nombre es más claro que por índice.

Escritura con csv.writer

csv.writer escribe listas de valores como filas CSV:

import csv

alumnos = [
    ["nombre", "ciclo", "nota"],
    ["Ana García", "DAW", 8.5],
    ["Carlos López", "DAM", 6.0],
    ["María Fernández", "DAW", 9.2],
    ["Pedro Martín", "ASIR", 5.5],
]

with open("alumnos.csv", "w", encoding="utf-8", newline="") as f:
    escritor = csv.writer(f)
    escritor.writerows(alumnos)

Para escribir fila a fila se usa writerow():

1
2
3
4
5
with open("alumnos.csv", "w", encoding="utf-8", newline="") as f:
    escritor = csv.writer(f)
    escritor.writerow(["nombre", "ciclo", "nota"])   # cabecera
    escritor.writerow(["Ana García", "DAW", 8.5])
    escritor.writerow(["Carlos López", "DAM", 6.0])

Escritura con csv.DictWriter

csv.DictWriter escribe diccionarios como filas. Hay que indicar los nombres de los campos en el parámetro fieldnames:

import csv

alumnos = [
    {"nombre": "Ana García",      "ciclo": "DAW",  "nota": 8.5},
    {"nombre": "Carlos López",    "ciclo": "DAM",  "nota": 6.0},
    {"nombre": "María Fernández", "ciclo": "DAW",  "nota": 9.2},
    {"nombre": "Pedro Martín",    "ciclo": "ASIR", "nota": 5.5},
]

campos = ["nombre", "ciclo", "nota"]

with open("alumnos.csv", "w", encoding="utf-8", newline="") as f:
    escritor = csv.DictWriter(f, fieldnames=campos)
    escritor.writeheader()     # Escribe la fila de cabecera
    escritor.writerows(alumnos)

Delimitadores personalizados

Por defecto csv.reader y csv.writer usan la coma como delimitador. Para usar el punto y coma (habitual en ficheros CSV de España y Europa):

import csv

with open("alumnos.csv", "r", encoding="utf-8", newline="") as f:
    lector = csv.reader(f, delimiter=";")
    for fila in lector:
        print(fila)

with open("alumnos.csv", "w", encoding="utf-8", newline="") as f:
    escritor = csv.writer(f, delimiter=";")
    escritor.writerow(["Ana García", "DAW", 8.5])

Antipatrón: parsear CSV manualmente con split()

# Incorrecto: falla si un campo contiene comas o está entre comillas
with open("alumnos.csv", "r", encoding="utf-8") as f:
    for linea in f:
        campos = linea.strip().split(",")
        nombre, ciclo, nota = campos
# Correcto: el módulo csv gestiona todos los casos correctamente
import csv
with open("alumnos.csv", "r", encoding="utf-8", newline="") as f:
    lector = csv.DictReader(f)
    for fila in lector:
        nombre = fila["nombre"]
        ciclo = fila["ciclo"]
        nota = float(fila["nota"])