Menu
Français

CSV Python : lire et écrire des fichiers CSV avec le module csv

Comment lire et écrire des fichiers CSV en Python — le module csv, DictReader et DictWriter, gérer les en-têtes, les guillemets, et quand utiliser pandas à la place.

Le CSV est plus simple qu'il n'y paraît (et plus délicat que tu ne l'attendrais)

Un fichier CSV, c'est juste du texte : des lignes séparées par des retours à la ligne, des champs séparés par des virgules. C'est l'idée. En pratique, tu tombes sur des chaînes entre guillemets qui contiennent des virgules, des champs avec des retours à la ligne intégrés, des conventions régionales différentes (virgule vs point-virgule), des fichiers sauvegardés depuis Excel qui incluent un BOM — assez de cas limites pour qu'écrire ton propre line.split(",") soit presque toujours une erreur.

Le module csv intégré de Python gère tout ça. Tu auras rarement besoin d'autre chose pour des fichiers petits à moyens.

Lire un CSV avec csv.reader

csv.reader produit chaque ligne comme une liste de chaînes :

import csv

with open("people.csv", newline="") as f:
    reader = csv.reader(f)
    for row in reader:
        print(row)

Quelques détails non évidents :

  • Passe toujours newline="" à open. Le module csv gère lui-même les fins de ligne ; sans ça, tu obtiens des lignes vides supplémentaires sur Windows.
  • Chaque valeur est une chaîne. "42" reste une chaîne jusqu'à ce que tu appelles int(...) dessus. CSV n'a pas de types.
  • La ligne d'en-tête est juste une autre ligne. Si ton fichier a des en-têtes, soit saute la première ligne manuellement, soit passe à DictReader.

Sauter la ligne d'en-tête

import csv

with open("people.csv", newline="") as f:
    reader = csv.reader(f)
    headers = next(reader)         # extrait la première ligne
    for row in reader:
        print(row)

next(reader) avance l'itérateur d'un cran et renvoie cette ligne.

Lire comme des dicts avec DictReader

csv.DictReader traite la première ligne comme en-têtes et te donne chaque ligne suivante comme un dict :

import csv

with open("people.csv", newline="") as f:
    reader = csv.DictReader(f)
    for row in reader:
        print(row["name"], row["email"])

C'est presque toujours ce que tu veux. Les noms de colonnes sont auto-documentés, et réordonner les colonnes dans le fichier source ne casse pas ton code.

Si le fichier n'a pas d'en-têtes, passe-les explicitement avec fieldnames=["name", "email", ...].

Écrire un CSV avec csv.writer

csv.writer transforme des lignes (listes) en lignes CSV :

import csv

rows = [
    ["name", "age", "city"],
    ["Rosa", 30, "Lisbon"],
    ["Ada", 36, "London"],
]

with open("out.csv", "w", newline="") as f:
    writer = csv.writer(f)
    writer.writerows(rows)

writerow(row) écrit une seule ligne ; writerows(rows) écrit tout un itérable d'un coup. Les deux mettent automatiquement des guillemets quand les champs contiennent des virgules, guillemets ou retours à la ligne — tu n'as pas à y penser.

Écrire des dicts avec DictWriter

Quand tes données sont déjà sous forme de dict, DictWriter saute l'étape « convertir en liste » :

import csv

people = [
    {"name": "Rosa", "age": 30, "city": "Lisbon"},
    {"name": "Ada", "age": 36, "city": "London"},
]

with open("out.csv", "w", newline="") as f:
    writer = csv.DictWriter(f, fieldnames=["name", "age", "city"])
    writer.writeheader()
    writer.writerows(people)

L'argument fieldnames contrôle à la fois l'en-tête et l'ordre des colonnes. Les clés de tes dicts qui ne sont pas dans fieldnames sont silencieusement supprimées (ou tu peux lever avec extrasaction="raise").

Différents délimiteurs et guillemets

Tous les « CSV » n'utilisent pas la virgule. Les locales européennes utilisent souvent ;, les fichiers séparés par tabulations utilisent \t, certains systèmes utilisent |. Passe un argument delimiter= :

import csv

with open("data.tsv", newline="") as f:
    reader = csv.reader(f, delimiter="\t")
    for row in reader:
        print(row)

Pour les fichiers avec des règles de guillemets inhabituelles, csv.register_dialect(...) te permet de configurer une fois et de réutiliser. Pour la plupart des fichiers, les défauts plus delimiter= suffisent.

Encodage

Les fichiers CSV sont du texte — ils ont des encodages. UTF-8 est le défaut moderne ; les fichiers originaires d'Excel sur Windows utilisent parfois cp1252 ou incluent un BOM UTF-8. Sois explicite :

with open("data.csv", newline="", encoding="utf-8") as f:
    reader = csv.DictReader(f)
    ...

Si tu vois UnicodeDecodeError, le fichier n'est pas dans l'encodage que tu as deviné. Essaie utf-8-sig (gère le BOM Excel), cp1252 ou latin-1 comme suspects courants.

Transformer les lignes CSV en types utiles

Puisque chaque valeur arrive comme une chaîne, le parsing est à toi :

main.py
Output
Click Run to see the output here.

(StringIO nous permet de lancer l'exemple sans vrai fichier — dans du vrai code tu ferais open(path).)

Pour les CSV avec des types délicats (dates, nombres nullable, true/false dans dix orthographes différentes), envisage pandas — il a des conventions intégrées pour la plupart.

Quand utiliser pandas

pandas.read_csv(path) renvoie une DataFrame, qui est la bonne structure au moment où tu veux :

  • Filtrer des lignes : df[df["active"] == True]
  • Agréger : df.groupby("city")["age"].mean()
  • Joindre avec une autre table
  • Réécrire avec un formatage simple
import pandas as pd

df = pd.read_csv("people.csv")
adults = df[df["age"] >= 18]
adults.to_csv("adults.csv", index=False)

Pandas est exagéré pour de petites lectures linéaires — et c'est une lourde dépendance (à pip-install dans un environnement virtuel). Mais pour tout ce qui a la forme de données, c'est l'outil que la plupart des analystes Python utilisent.

Streamer de très gros fichiers

csv.reader est déjà paresseux — il lit une ligne à la fois. Garde-le ainsi en itérant (ne pas appeler list(reader) à l'avance), et ta mémoire reste plate peu importe la taille du fichier :

import csv

with open("huge.csv", newline="") as f:
    reader = csv.DictReader(f)
    error_count = 0
    for row in reader:
        if row["status"] == "error":
            error_count += 1

print(f"Found {error_count} errors.")

Ça gère un fichier de 10 Go aussi volontiers qu'un de 10 Ko, tant que tu n'accumules pas les lignes dans une liste.

Quelques habitudes

  • Passe toujours newline="" à open en lisant ou écrivant des CSV.
  • Utilise DictReader/DictWriter dès que le fichier a des en-têtes — plus lisible que des indices entiers.
  • Sois explicite sur l'encodage, surtout avec des fichiers d'Excel ou de sources non anglaises.
  • Convertis les types directement à la lecture pour que le code en aval n'ait pas à le faire.
  • Utilise pandas dès que tu veux analyser les données, pas juste les déplacer.

Ensuite

Tu peux maintenant lire JSON et CSV. La dernière compétence du monde réel qu'on va couvrir, c'est récupérer des données sur le réseau — c'est le prochain doc, sur les requêtes HTTP avec la bibliothèque requests.

Questions fréquentes

Comment lire un fichier CSV en Python ?

Utilise le module csv intégré. csv.reader te donne chaque ligne comme une liste de chaînes ; csv.DictReader utilise la première ligne comme en-têtes et produit chaque ligne comme un dict. Ouvre le fichier avec newline='' pour que Python ne massacre pas les fins de ligne : with open('data.csv', newline='') as f:.

Comment écrire un fichier CSV en Python ?

Associe csv.writer à un fichier ouvert en mode écriture et newline=''. Appelle writer.writerow([...]) pour chaque ligne ou writer.writerows([[...], [...]]) pour un lot. Pour des données sous forme de dict, utilise csv.DictWriter — il gère les en-têtes automatiquement.

Dois-je utiliser le module csv ou pandas ?

Utilise csv pour des lectures et écritures rapides, des fichiers que tu traites ligne par ligne, et quand tu ne veux pas une dépendance de plus. Utilise pandas quand tu as besoin de filtrer, grouper ou joindre — ou quand le fichier est assez grand pour que les opérations vectorisées comptent. Ils gèrent les mêmes fichiers ; le choix porte sur ce que tu fais des données après chargement.

Pourquoi mon CSV a-t-il des lignes blanches entre les lignes sur Windows ?

Tu as ouvert le fichier sans newline=''. Le module csv écrit ses propres terminateurs de ligne ; sans cet argument, Python en ajoute d'autres sur Windows. Ouvre toujours les fichiers CSV avec open(path, newline='') à la fois en lecture et écriture.

Apprendre à coder avec Coddy

COMMENCER