Aller au contenu

Lire un fichier csv et dictionnaire python

On va ouvrir le même fichier personnes.csv et effectuer des tâches assez proches de celles de la page précédente mais en utilisant cette fois une structure de dictionnaire-python.

Le contenu du fichier.

Vous pouvez ouvrir le fichier personnes.csv avec un éditeur de texte ou un tableur pour visualiser son contenu.

Rappel du contenu

Ce contenu est le suivant:

id_personne nom prenom anneeNaissance
1 Labrosse Adam 2000
2 Gemlamorte Adèle 1985
3 Auboisdormant Abel 2001
4 Etpan Ahmed 1975
5 Térieur Alain 1999
6 Térieur Alex 1976
7 Proviste Alain 2000
8 Verse Alain 1970
9 Ception Alex 2001
10 Ainé Ali 1975
11 Gator Ali 2001
12 Bistraux Alonzo 2001
13 Patamob Alphonse 1970
14 Ficulté Andy 1980
15 Rectdustade Andy 2000
16 Verserre Annie 2001
17 Boréal Aurore 1985
18 Nor Paul 1985
19 Dejeu Bernadette 2001
20 Dajeun Bruno 1984
21 Hiple Candice 2000

Avec un dictionnaire

Python nous autorise aussi à travailler avec un dictionnaire pour chaque ligne. L'avantage de ce choix est que l'on va pouvoir rappeler l'entête des colonnes du fichier csv à l'aide des clefs du dictionnaire.

import csv

# ouverture en lecture du fichier csv
with open('personnes.csv', newline='') as fichier:
    # on crée un objet DictReader
    lecture = csv.DictReader(fichier, delimiter=',')

    # quelques affichages:
    for ligne in lecture:
        print(ligne['nom'])

Comme précédemment, l'objet DictReader est un itérateur: on le transformera en liste pour accèder directement par les numéros de ligne:

import csv

# ouverture en lecture du fichier csv
with open('personnes.csv', newline='') as fichier:
    # on crée un objet DictReader
    lecture = csv.DictReader(fichier, delimiter=',')

    # transfo en liste
    lignes = list(lecture)


for ligne in lignes:
    print(ligne)

La ligne 0 d'entête qui pouvait nous gêner avec l'objet reader a maintenant disparu (l'entête est utilisé pour les noms des clefs, ce n'est pas considéré comme une donnée).

Le début du résultat de la précédente lecture:

OrderedDict([('id_personne', '1'), ('nom', 'Labrosse'), ('prenom', 'Adam'), ('anneeNaissance', '2000')])
OrderedDict([('id_personne', '2'), ('nom', 'Gemlamorte'), ('prenom', 'Adèle'), ('anneeNaissance', '1985')])
OrderedDict([('id_personne', '3'), ('nom', 'Auboisdormant'), ('prenom', 'Abel'), ('anneeNaissance', '2001')])
OrderedDict([('id_personne', '4'), ('nom', 'Etpan'), ('prenom', 'Ahmed'), ('anneeNaissance', '1975')])

Si l'on veut afficher par exemple le nom de la personne d'identifiant égal à 3:

import csv

# ouverture en lecture du fichier csv
with open('personnes.csv', newline='') as fichier:
    # on crée un objet DictReader
    lecture = csv.DictReader(fichier, delimiter=',')

    # transfo en liste
    lignes = list(lecture)


def nom_d_identifiant(identifiant):
    """
    identifiant -- entier naturel (identifiant d'une personne)

    renvoie le nom de la personne ayant identifiant 
    pour valeur de id_personne.
    """
    for personne in lignes:
        if int(personne['id_personne'])  == identifiant:
            return personne['nom'] 
    # on renvoie None si l'identifiant n'existe pas:
    return None 


# test
print(nom_d_identifiant(3))

On obtient:

Auboisdormant

Note

Vous traiterez les exercices qui suivent avec un objet DictReader et non un objet reader.

Sélection suivant un critère et sans doublon

Écrire une fonction qui renvoie la liste des noms de personnes dont le nom commence par une lettre (cette lettre est un paramètre de la fonction).

La liste ne contiendra pas de doublon (par exemple, avec la lettre T, on n'aura pas deux "Térieur" dans la liste).

def commencePar(lettre):
    """
    lettre -- lettre majuscule

    renvoie la liste des noms de personnes  
    dont l'initiale du nom est lettre.
    """
un code possible
import csv

# ouverture en lecture du fichier csv
with open('personnes.csv', newline='') as fichier:
    # on crée un objet DictReader
    lecture = csv.DictReader(fichier, delimiter=',')

    # transfo en liste
    lignes = list(lecture)


def commencePar(lettre):
    """
    lettre -- lettre majuscule

    renvoie la liste des noms de personnes  
    dont l'initiale du nom est lettre.
    """
    liste = []
    for personne in lignes:
        if personne['nom'][0] == lettre and personne['nom'] not in liste:
            liste.append(personne['nom'])
    return liste


# test
print(commencePar('B'))
print(commencePar('T'))

Vérifier l'unicité

Écrire un code possible pour le corps de la fonction suivante:

def AllDiff(champ):
    """
    champ -- l'une des clefs du dictionnaire  lignes

    renvoie True si toutes les données-lignes 
    ont des valeurs de champ distinctes
    et renvoie False sinon.
    >>> AllDiff('nom') # il existe au moins deux noms identiques
    False
    >>> AllDiff('id_personne') # tous les id sont distincts
    True 
    """

Principe

On construit une liste dans laquelle on ajoute au fur et à mesure de la lecture les nouvelles valeurs. Si la nouvelle valeur lue est déjà présente dans la liste, on renvoie "faux".

Solution
import csv

# ouverture en lecture du fichier csv
with open('personnes.csv', newline='') as fichier:
    # on crée un objet DictReader
    lecture = csv.DictReader(fichier, delimiter=',')

    # transfo en liste
    lignes = list(lecture)


def AllDiff(champ):
    """
    champ -- l'une des clefs  

    renvoie True si toutes les données-lignes 
    ont des valeurs de champ distinctes
    et renvoie False sinon.
    >>> AllDiff('nom') # il existe au moins deux noms identiques
    False
    >>> AllDiff('id_personne') # tous les id sont distincts
    True 
    """
    liste = []
    for personne in lignes:
        if personne[champ] in liste: return False
        liste.append(personne[champ])
    return True   

Sélection multi-critères, sans doublon

Écrire un code possible pour le corps de la fonction suivante:

def finEnEtNeApres(lettre, annee):
    """
    lettre -- une lettre en minuscule
    annee -- une année


    renvoie la liste, sans doublon, des noms de personnes
    dont le prénom se termine par lettre et qui sont nés après annee.
    >>> finEnEtNeApres('e', 1980)
    ['Gemlamorte', 'Verserre', 'Boréal', 'Dejeu', 'Hiple']
    """
Solution
import csv

# ouverture en lecture du fichier csv
with open('personnes.csv', newline='') as fichier:
    # on crée un objet DictReader
    lecture = csv.DictReader(fichier, delimiter=',')

    # transfo en liste
    lignes = list(lecture)


# on transforme les années de Naissance en entier
for personne in lignes:
    personne['anneeNaissance'] = int(personne['anneeNaissance'])


def finEnEtNeApres(lettre, annee):
    """
    lettre -- une lettre en minuscule
    annee -- une année


    renvoie la liste, sans doublon, des noms de personnes
    dont le prénom se termine par lettre et qui sont nés après annee.
    >>> finEnEtNeApres('e', 1980)
    ['Gemlamorte', 'Verserre', 'Boréal', 'Dejeu', 'Hiple']
    """
    liste = []
    for personne in lignes:
        if personne['prenom'][-1] == lettre and personne['anneeNaissance'] > annee:
            if personne['nom'] not in liste:
                liste.append(personne['nom'])
    return liste