W3docs

Fichiers CSV en Python

Apprenez à lire et écrire des fichiers CSV en Python avec le module csv intégré : csv.reader, csv.writer, DictReader et DictWriter avec des exemples pratiques.

CSV (Comma-Separated Values, valeurs séparées par des virgules) est l'un des formats les plus courants pour l'échange de données tabulaires — chaque tableur, base de données et outil de science des données peut lire et écrire ce format. Le module csv intégré à Python gère automatiquement les parties délicates : l'ajout de guillemets autour des champs contenant des virgules, la gestion des fins de ligne selon les systèmes d'exploitation et le mappage des lignes vers des dictionnaires. Vous n'avez rien à installer ; csv est livré avec toute installation Python.

Ce chapitre couvre la lecture de fichiers CSV, l'écriture de fichiers CSV, l'utilisation de DictReader et DictWriter, la gestion des délimiteurs personnalisés et les pièges courants à éviter.

Qu'est-ce qu'un fichier CSV ?

Un fichier CSV est un fichier texte brut où chaque ligne représente une ligne de données et chaque champ au sein d'une ligne est séparé par un délimiteur — généralement une virgule. Voici un exemple minimal :

name,age,city
Alice,30,New York
Bob,25,London

La première ligne est généralement un en-tête qui nomme chaque colonne. Les lignes suivantes contiennent les données réelles. Si la valeur d'un champ contient elle-même une virgule, le champ est entouré de guillemets doubles :

name,bio
Alice,"Engineer, New York"

Le module csv gère ces guillemets de manière transparente, vous n'avez donc pas besoin d'analyser le fichier manuellement.

Lecture de fichiers CSV avec csv.reader

csv.reader transforme un fichier ouvert (ou tout itérable de chaînes) en un itérateur qui produit chaque ligne sous forme de liste Python.

Schéma de base — lire un fichier CSV ligne par ligne

import csv

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

L'argument newline="" est important. Sans lui, la traduction universelle des fins de ligne de Python peut insérer des lignes vides supplémentaires sous Windows, car le module csv gère lui-même les fins de ligne en interne.

En supposant que people.csv contienne les données d'exemple ci-dessus, la sortie est :

['name', 'age', 'city']
['Alice', '30', 'New York']
['Bob', '25', 'London']

Notez que toutes les valeurs — y compris le nombre 30 — sont renvoyées sous forme de chaînes. Le module csv n'infère pas les types de données ; convertissez-les vous-même si nécessaire.

Ignorer la ligne d'en-tête

Lorsque vous ne voulez que les lignes de données et non l'en-tête, appelez next() sur le lecteur une fois pour consommer la première ligne :

Ignorer la ligne d'en-tête avec next()

import csv

with open("people.csv", newline="") as f:
    reader = csv.reader(f)
    header = next(reader)          # consume and store the header
    print("Columns:", header)
    for row in reader:             # only data rows remain
        name, age, city = row
        print(f"{name} is {age} years old and lives in {city}.")

Sortie :

Columns: ['name', 'age', 'city']
Alice is 30 years old and lives in New York.
Bob is 25 years old and lives in London.

Charger toutes les lignes dans une liste

Si vous avez besoin de tout le fichier en mémoire en une seule fois, passez le lecteur à list() :

import csv

with open("people.csv", newline="") as f:
    reader = csv.reader(f)
    rows = list(reader)

print(rows[0])   # header row
print(rows[1])   # first data row

Sortie :

['name', 'age', 'city']
['Alice', '30', 'New York']

Écriture de fichiers CSV avec csv.writer

csv.writer écrit des lignes dans tout objet similaire à un fichier, en ajoutant automatiquement des guillemets autour des champs contenant le délimiteur, des guillemets doubles ou des caractères de fin de ligne.

Écrire des lignes dans un nouveau fichier CSV

import csv

rows = [
    ["product", "price", "quantity"],
    ["Apple", 1.2, 50],
    ["Banana", 0.5, 100],
    ["Cherry", 3.0, 30],
]

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

Après l'exécution, inventory.csv contient :

product,price,quantity
Apple,1.2,50
Banana,0.5,100
Cherry,3.0,30

Utilisez writer.writerow(row) pour écrire une seule ligne, ou writer.writerows(rows) pour en écrire plusieurs à la fois. Les deux acceptent tout itérable.

Pourquoi newline="" est important lors de l'écriture

Sous Windows, Python ouvre les fichiers texte dans un mode qui traduit \n en \r\n. Le module csv écrit également des fins de ligne \r\n par défaut. Ensemble, ils produisent \r\r\n — une ligne vide entre chaque ligne lorsque le fichier est ouvert dans un autre programme. Passer newline="" supprime la traduction supplémentaire et laisse csv gérer les fins de ligne lui-même.

Lecture de fichiers CSV avec csv.DictReader

DictReader mappe chaque ligne vers un OrderedDict (ou un dict ordinaire en Python 3.8+) dont les clés sont les noms de colonnes de la ligne d'en-tête. C'est l'approche recommandée lorsque les colonnes ont des noms significatifs et que vous souhaitez y accéder par nom plutôt que par index.

Lire un fichier CSV sous forme de séquence de dictionnaires

import csv

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

Sortie :

Alice — New York
Bob — London

DictReader lit automatiquement la première ligne comme en-tête. Vous pouvez remplacer ce comportement en passant un argument fieldnames :

import csv

# File has no header; provide field names explicitly
with open("data_no_header.csv", newline="") as f:
    reader = csv.DictReader(f, fieldnames=["name", "age", "city"])
    for row in reader:
        print(row)

L'attribut reader.fieldnames contient toujours la liste des noms de colonnes en cours d'utilisation, ce qui est pratique pour l'introspection avant le traitement des lignes.

Écriture de fichiers CSV avec csv.DictWriter

DictWriter est le pendant de DictReader. Vous fournissez les noms de colonnes à l'avance, puis vous écrivez des dictionnaires — le writer mappe chaque clé vers la colonne correcte.

Écrire une liste de dictionnaires dans un fichier CSV

import csv

people = [
    {"name": "Alice", "age": 30, "city": "New York"},
    {"name": "Bob", "age": 25, "city": "London"},
]

fieldnames = ["name", "age", "city"]

with open("people_out.csv", "w", newline="") as f:
    writer = csv.DictWriter(f, fieldnames=fieldnames)
    writer.writeheader()          # writes the column-name row
    writer.writerows(people)

Le fichier résultant :

name,age,city
Alice,30,New York
Bob,25,London

writeheader() utilise la liste fieldnames fournie lors de la construction. Appelez-la une seule fois avant tout appel à writerow().

Gestion des clés supplémentaires ou manquantes

Par défaut, DictWriter lève une ValueError si un dictionnaire contient une clé absente de fieldnames. Vous pouvez modifier ce comportement avec le paramètre extrasaction :

writer = csv.DictWriter(f, fieldnames=fieldnames, extrasaction="ignore")

À l'inverse, si un dictionnaire ne possède pas une clé, le writer écrit une chaîne vide pour ce champ, sauf si vous fournissez une valeur par défaut restval :

writer = csv.DictWriter(f, fieldnames=fieldnames, restval="N/A")

Délimiteurs et guillemets personnalisés

Les fichiers CSV du monde réel ne sont pas toujours délimités par des virgules. Les fichiers à valeurs séparées par des tabulations (TSV) et les fichiers délimités par des barres verticales sont courants. Utilisez le paramètre delimiter pour les gérer :

Lire un fichier séparé par des tabulations

import csv

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

Écrire un fichier délimité par des barres verticales

import csv

with open("output.psv", "w", newline="") as f:
    writer = csv.writer(f, delimiter="|")
    writer.writerow(["id", "name", "score"])
    writer.writerow([1, "Alice", 98])
    writer.writerow([2, "Bob", 87])

Fichier de sortie :

id|name|score
1|Alice|98
2|Bob|87

Constantes de guillemets

Le paramètre quoting contrôle quels champs sont mis entre guillemets dans la sortie :

ConstanteValeurComportement
csv.QUOTE_MINIMAL0Mettre entre guillemets uniquement les champs contenant le délimiteur, le caractère de citation ou un saut de ligne (par défaut)
csv.QUOTE_ALL1Mettre tous les champs entre guillemets
csv.QUOTE_NONNUMERIC2Mettre entre guillemets tous les champs non numériques ; le lecteur convertit les champs sans guillemets en float
csv.QUOTE_NONE3Ne jamais mettre entre guillemets ; lever une erreur si le délimiteur apparaît dans un champ

Forcer tous les champs à être mis entre guillemets

import csv, io

output = io.StringIO()
writer = csv.writer(output, quoting=csv.QUOTE_ALL)
writer.writerow(["name", "bio"])
writer.writerow(["Alice", "Engineer, New York"])
print(output.getvalue())

Sortie :

"name","bio"
"Alice","Engineer, New York"

Utilisation de io.StringIO pour les CSV en mémoire

Lorsque vous n'avez pas besoin d'accéder au système de fichiers — par exemple dans des tests ou lors du traitement de données CSV reçues depuis une API — utilisez io.StringIO comme objet similaire à un fichier :

Analyser un CSV à partir d'une chaîne

import csv
import io

raw = "name,score\nAlice,95\nBob,87\n"

reader = csv.DictReader(io.StringIO(raw))
for row in reader:
    print(row["name"], "scored", row["score"])

Sortie :

Alice scored 95
Bob scored 87

Pièges courants

Toutes les valeurs sont des chaînes

csv.reader et DictReader retournent toujours des chaînes. Convertissez les valeurs explicitement :

age = int(row["age"])
price = float(row["price"])

Problèmes d'encodage

Ouvrez les fichiers avec le bon encodage pour éviter les erreurs UnicodeDecodeError. UTF-8 est l'encodage le plus courant pour les fichiers CSV modernes, mais les fichiers exportés depuis Excel peuvent utiliser latin-1 ou cp1252 :

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

Lignes vides

Si votre fichier CSV contient des lignes vides entre les lignes de données, csv.reader produit des listes vides [] pour celles-ci. Filtrez-les :

import csv

with open("data.csv", newline="") as f:
    reader = csv.reader(f)
    for row in reader:
        if not row:        # skip blank lines
            continue
        print(row)

Gestion des erreurs

Encapsulez les opérations sur les fichiers dans un bloc try/except pour gérer les fichiers manquants et les erreurs de permission de manière appropriée :

import csv

try:
    with open("data.csv", newline="") as f:
        reader = csv.reader(f)
        for row in reader:
            print(row)
except FileNotFoundError:
    print("Error: data.csv was not found.")
except PermissionError:
    print("Error: no permission to read data.csv.")

csv versus Pandas pour les grands fichiers

Le module csv est idéal pour :

  • Les fichiers de petite à moyenne taille (jusqu'à quelques centaines de Mo)
  • Les scripts qui n'ont pas Pandas installé
  • Les situations où vous avez besoin d'un contrôle précis sur la lecture et l'écriture

Pour les grands ensembles de données, le filtrage complexe ou les opérations d'agrégation, la bibliothèque tierce pandas fournit pd.read_csv() et DataFrame.to_csv(), qui sont nettement plus rapides et plus riches en fonctionnalités.

Tout assembler

L'exemple suivant lit un fichier CSV, filtre les lignes selon une condition et écrit les résultats filtrés dans un nouveau fichier :

Filtrer des lignes et écrire un nouveau fichier CSV

import csv

input_file = "inventory.csv"
output_file = "expensive.csv"

with open(input_file, newline="") as infile, \
     open(output_file, "w", newline="") as outfile:

    reader = csv.DictReader(infile)
    writer = csv.DictWriter(outfile, fieldnames=reader.fieldnames)

    writer.writeheader()
    for row in reader:
        if float(row["price"]) >= 1.0:
            writer.writerow(row)

print(f"Filtered rows written to {output_file}.")

Ce schéma — ouvrir les deux fichiers dans le même bloc with, diffuser les lignes du lecteur vers le writer — gère des fichiers de toute taille sans tout charger en mémoire en une seule fois.

Chapitres connexes

Exercice

Pratique
Which csv module class maps each CSV row to a dictionary keyed by column names?
Which csv module class maps each CSV row to a dictionary keyed by column names?
Was this page helpful?