Aller au contenu

Import d'un fichier csv dans une liste de dictionnaire

Avec le module csv

On considère à nouveau le fichier temperatures_2020.csv. Ce fichier regroupe les températures minimales, maximales et moyennes dans différentes régions françaises pour certains jours de l'année 2020. Il est dans le dossier de travail et est encodé en utf-8.

Les premières lignes du fichier sont données ci-dessous :

📑 Données CSV
mois,jour,région,tmin,tmax,tmoy
août,13,Pays de la Loire,19.25,25.35,22.3
août,13,Occitanie,17.51,26.55,22.03
Activité 1 - Repérer les bonnes informations

Observez l'extrait proposé et répondez aux questions suivantes :

  1. Quel est le séparateur utilisé ?
  2. Combien y-a-t-il de descripteurs ?
  3. Quels sont les types des descripteurs ? (entier, nombre décimal, chaîne de caractères...)
Solution
  1. Le séparateur est la virgule
  2. Il y a six descripteurs
  3. mois et région sont des chaînes de caractères, jour est un entier, les trois autres sont des flottants.

Le module csv de Python permet d'importer facilement des fichiers csv vers des listes de dictionnaires. La démarche est la suivante :

  • ouvrir le fichier csv,

  • crĂ©er un objet de type csv.DictReader (voir plus bas),

  • l'utiliser pour lire les donnĂ©es du fichier et les convertir en dictionnaire.

Le code alors très concis :

Important

Prenez le temps de lire les commentaires !

Cliquez sur les +

import csv
with open("temperatures_2020.csv", "r", encoding="utf-8") as fichier:
    lecteur = csv.DictReader(fichier, delimiter=",")  # (1)
    temperatures = [entree for entree in lecteur]  # (2)
  1. Un objet csv.DictReader prend deux arguments : le fichier à lire et le séparateur
  2. Les entree obtenues lors du parcours du lecteur sont des dictionnaires. On crée une liste en compréhension.
Comment Python connaît-il les descripteurs ?

Le comportement par défaut de csv.DictReader est de chercher les noms des descripteurs sur la première ligne du fichier. On utilise ce comportement ici.

Si la première ligne comprend des données et que les descripteurs ont été récupérés ailleurs, on peut les passer en argument (sous forme d'une liste par exemple) en faisant lecteur = csv.DictReader(fichier, delimiter=",", fieldnames=descripteurs)

Python < 3.8

Pour les versions précédentes de Python (avant la 3.8), il faut faire une conversion : temperatures.append(dict(entree))

Typage des données

Le module csv nous simplifie grandement la tâche mais il ne fait pas tout : les données ne sont pas typées :

temperatures = [
    {"mois": "août", "jour": "13", "région": "Pays de la Loire", "tmin": "19.25", "tmax": "25.35", "tmoy": "22.3"},
    {"mois": "août", "jour": "13", "région": "Occitanie", "tmin": "17.51", "tmax": "26.55", "tmoy": "22.03"},
    {"mois": "août", "jour": "14", "région": "Pays de la Loire", "tmin": "17.7", "tmax": "25.7", "tmoy": "21.7"},
    ...
]

Le typage s'apparente à celui effectué dans le cas d'une liste de listes. Il est néanmoins plus simple sur un point : on peut directement utiliser le nom des descripteurs plutôt que leurs indices.

Activité 2 - Import et typage complets

Compléter le script ci-dessous permettant d'importer et de typer convenablement les données du fichier temperatures_2020.csv.

Ordre de lecture

Le test de validation compare votre liste avec la liste obtenue en lisant le fichier dans l'ordre des lignes (comme proposé partout dans ce cours).

Le test Ă©chouera donc si vous ne parcourez pas les lignes du fichier dans l'ordre...

###(Dés-)Active le code après la ligne # Tests (insensible à la casse)
(Ctrl+I)
Tronquer ou non le feedback dans les terminaux (sortie standard & stacktrace / relancer le code pour appliquer)
Si activé, le texte copié dans le terminal est joint sur une seule ligne avant d'être copié dans le presse-papier
Évaluations restantes : 10/10

.128013rt=7flb)D1 2e/vygj.:,-]8TswR9nuph5aS(o3qk_i46P;[cdxm0050Y0n0c0J0R0g0A0l0X0g0J0A0A0d010c0R0G010406050A0F0!0!0J0b0q040K0M0g0F0_0M0E050o101214160~0G04051m1f1p0o1m0~0Y0R0p0.0:0=0@0H0R0r0H0g1D0H0c0|050)0h0g0n1y0;0?011C1E1G1E0c1M1O1K0c0b1n0c0H0.190A0G0J0E0@0m011Q1A010f0+0n0E0J0!0n1K1-1/1@1S1`1O1}1 0|0a0l0U0b0M0G0M0A0R1c0E0l0%1+0b0b0n0X2k1f220E1n0o1)2x1$1(1%1L0Y240@1G0E1|2h1K1v1x0/1R2H0R2J0E0M2N1K0G2q1n2v2x2#0 1.2l2P1^2U0b130g0|0l0k2u2)0}2(232+1S2-2/2;0m2@1/2_2v2G012~0J2:040l0N322w0~352|0@383a0l0S3e342)363k2;0I3o3g3q3i370M2.392;0T3v2`2*1z2}3A2 3b0e3F3h3I3j3K3C3b0y3O3x3Q3z3B3l0D3W2{3Y3s040k0#3%3H2Q3Z3L0k2?1g2^3w3(3:3*0k313^333`3/2,3S3a0k3d402w1q2Z1f2N2A0Y1(2F3y0X2V201n4e1o4c2%491n4k0%2!3X3:0P0E0|0R0!2g0b0c3o0l3G3r4A040X0A0p3v42360P0|0B2j0H4H4J3y0E0h0|2f1|3o4Z3Y0{040L4*3P3:0A1=04020O0F0M0c0V0c0n4D0n0b0J0c0F2q0A0Q0m0#5a0t4N0p4_4{4}4:4x1^4-0v4Y4;1^4?0|5g4|0V0b5t5i4s4+3:5m5o5k2}0|1|4u2S0r5j3{1^0M0|0d5L431S5r4^4`5u1b0f0w0y5x0V5R364-0i5D5M1S4T040;5,5S3j0|1`0X1C525(3y4-0u3v0l624I5p5F041O2s0n565=365O045Q4s645E5@4M4O5}3Y6e0t6n3|0|0j0R2s0C0n0J0%0b6r5l0|4/5z656k5_5{6B6G6j015C6h5A2,0|0%1G0!2j5|6M5-0@6e6g2%6H015U5$0v5$6C1S5*61636R664 515355576c3y6$6~4,0|0W6/6k1|1$0n0n714y5^3A7b6S04772q7a6Q6)0M0B4B1e7l6N4L684 6b6Z5?6O0|0x4Q4R4j0k0|030l0z0q1.0r7k2#7D3Y5/0f7e7r6!375G0E787N2^6i7V7n7p7f6^500G5254560n0A757z04604s06637$7y4L7i797?4-747x366+5W4}0s0M566.855~7A7*6#5P8h374$042S4G8e724.7?7 7Y7j82737?875h0V8a8c885%8q5B7A5+7`7|6@768v818H6D04846(6N8A5u0c6W0E8d8V7V4-7B7U7y708+3r8m0f0g0M548x8s8R66807!338N7@8U2^8 8X4}8Z2S8$926)8)8K7O8M6)8u7Z8^918~6)944~130Z989k6N8)8k8-2#7}8/5^8=8@8`0@4-6F8%7~7X9h9C908z4@5$8Z0J9p8F8^0x9c3_9e7s9I8w9K839M5s8F8Z0M0q9q4a9a8g8.6 8j9;3)8:9A8p9G5)6E8t9Z8Q9|8f8T9%5V8B9*9,9S9#8J3F0o4u0n2x2Yag4d1w4f2A2D2y0J1Naj0o4e0~at0(0*0,04.
Remarque

La méthode proposée ici lit deux fois l'ensemble des informations :

  • une fois lors de l'import,
  • une fois lors du typage.

Il est possible de faire ces deux actions en une seule passe :

import csv

temperatures = []
with open("temperatures_2020.csv", "r", encoding="utf-8") as fichier:
    lecteur = csv.DictReader(fichier, delimiter=",")
    for entree in lecteur:
        entree["jour"] = int(entree["jour"])
        entree["tmin"] = float(entree["tmin"])
        entree["tmax"] = float(entree["tmax"])
        entree["tmoy"] = float(entree["tmoy"])
        temperatures.append(entree)

Ă€ la main !

Il est possible d'effectuer les mêmes actions sans utiliser le module csv. La démarche est un peu plus longue mais permet de bien comprendre le fonctionnement.

L'idée est la suivante :

  • ouvrir le fichier,
  • rĂ©cupĂ©rer les noms des descripteurs Ă  l'aide de la première ligne du fichier,
  • pour chaque ligne restant Ă  lire :
    • la nettoyer et la dĂ©couper,
    • crĂ©er un dictionnaire associant les noms des descripteurs aux valeurs,
    • ajouter ce dictionnaire Ă  la liste gĂ©nĂ©rale.

Conseil

On pourra (re)lire avec intérêt la page sur les fichiers

Activité 3 - Récupérer les noms des descripteurs

On considère un fichier csv dont le séparateur est le point-virgule.

Quelle(s) instruction(s) permet(tent) de récupérer les descripteurs ?

  • with open("fichier.csv", "r", encoding="utf-8") as fichier:
        for ligne in fichier:
            descripteurs = ligne.split(",")
    
  • with open("fichier.csv", "r", encoding="utf-8") as fichier:
        ligne = fichier.readline()
        ligne_propre = ligne.strip()
        descripteurs = ligne_propre.split(",")
    
  • with open("fichier.csv", "r", encoding="utf-8") as fichier:
        ligne = fichier.readline()
        descripteurs = ligne.strip().split(",")
    
  • with open("fichier.csv", "r", encoding="utf-8") as fichier:
        descripteurs = fichier.readline().strip().split(",")
    
  • ❌ On rĂ©cupère ainsi les donnĂ©es de chaque ligne...
    with open("fichier.csv", "r", encoding="utf-8") as fichier:
        for ligne in fichier:
            descripteurs = ligne.split(",")
    
  • âś… En trois temps :
    with open("fichier.csv", "r", encoding="utf-8") as fichier:
        ligne = fichier.readline()  # on lit la 1ère ligne
        ligne_propre = ligne.strip()  # on efface le \n
        descripteurs = ligne_propre.split(",")  # on découpe à chaque ","
    
  • âś… En trois temps aussi mais sur deux lignes :
    with open("fichier.csv", "r", encoding="utf-8") as fichier:
        ligne = fichier.readline()  # lecture de la 1ère ligne
        descripteurs = ligne.strip().split(",")  # nettoyage et découpage
    
  • âś… Tout en une seule ligne, ce n'est pas très clair !
    with open("fichier.csv", "r", encoding="utf-8") as fichier:
        descripteurs = fichier.readline().strip().split(",")
    
Activité 4 - Import dans une liste de dictionnaires à la main

Compléter le script ci-dessous permettant d'importer les données du fichier temperatures_2020.csv dans une liste de dictionnaires. On n'utilisera pas le module csv.

Ordre de lecture

Le test de validation compare votre liste avec la liste obtenue en lisant le fichier dans l'ordre des lignes (comme proposé partout dans ce cours).

Le test Ă©chouera donc si vous ne parcourez pas les lignes du fichier dans l'ordre...

###(Dés-)Active le code après la ligne # Tests (insensible à la casse)
(Ctrl+I)
Tronquer ou non le feedback dans les terminaux (sortie standard & stacktrace / relancer le code pour appliquer)
Si activé, le texte copié dans le terminal est joint sur une seule ligne avant d'être copié dans le presse-papier
Évaluations restantes : 10/10

.128013rt=7flOb)1 {2e/vyg.:,-]8swR9nuph5aS(oq3k_}i46;PĂ©[cdm0050Z0o0c0I0R0g0z0l0Y0g0I0z0z0d010c0R0F010406050z0E0!0!0I0b0r040J0L0g0E0_0L0D0l020I0!0F0U0l0B0o130b0M0E0o0z050p101214160~0F04051B1u1E0p1B0~0Z0R0q0.0:0=0@0G0R0s0G0g1S0G0c0|050)0i0g0o1N0;0?011R1T1V1T0c1#1%1Z0c0b1C0c0G0.190z0F0I0D0@0n011)1P010f0+0o0D1h0o1Z1 21261+291%2c0!2e040a0l0V0b0L0F0L0z0R1c1e0%1}0b0b0o0Y2z1u2g0D1C0p1{2L1^1`1_1!0Z2i0@1V0D2b2w1Z1K1M0/1*2V0R2X0D0L2#1Z0F2E1C2J2L2?0 201e2%272,0b130g0|0l0k2I2`0}2_2h2|1+2~30320n3521372J2U013c0I31040l0N3g2K0~3j3a0@3m3o0l0S3s3i2`3k3y320H3C3u3E3w3l0L2 3n320T3J382{1O3b3O3d3p0e3T3v3W3x3Y3Q3p0y3$3L3(3N3P3z0C3.393:3G040k0#3^3V2(3;3Z0k341v363K3_413{0k3f463h1F2;1u2#2O0Z1`2T3M0Y2-2o0$1L1C2:0o2=363C054p0%4x492}0|0c1n0F0o0b0I0c0E2E1t4e2K0l3U3k0L0|0d3C4T3%410{040X0x3 3k0O0|0A2y0G4Z4U3M0D0i0|2u2b4z4#274%0K4}3/4a0|2k0o524E1+4W044Y4R4D40270z2404021q0L0c0U4H1i4K4M4O1s0P0n0#5x0t0Y0z0q5l0E5n0U585g1+4%0v4=4~3b0|0!4q5I4V4X5T3M5i0|5E5G0b5!5o5W3:5L5N534F042b4B2*0s5)415b5d2^5O0@5Y5k5m5o1b0f0w0y5%5H5e4?5*0|0j5,590@4-040;6d5J3x550R0Y1R4K5@4 0|0u3J0l6w4!5-5P041/2X6j5U5c6E4@6m6o0R6q685|015b0t6r6A2E0I0Z2W576N6z0@506c5e066x6y6e3l0|6C0o0P2:2u2E6H3:5_6^546B1S6D6Z6,6Q6S6l040z1^0`73016$6v6x696|0%0z0Y0b0`4H4O4Q2?6+6k6P5V5e7p3F6.6~6:6=4v7972707q0D0|1 1V0c7950795~660v667K6b7c6w7e276g0f3O6{5.6/7!5a0A0|2*7%74296K6M5{6!7a6t7T6*7u6I6}0s2X6;2t7A7t7V5a7s7o83747$7D6F6R8a7{767j0F7R040K6%2?6)7_7U6O7F040q3n0o7m7,7r6G828q7w7}7y806@8d6_0|8c7;6,8r7H2y8i518H417N600U7P8V8i8l478o8p7=8r1K4p8x6`8A7=4%0m0Q7^6*87017X7Z8.8M7*8,7)047+8|7E4_044L0D0s6Y8L7q7L8S2}952l8Q798)1s7i7k8v0b7n4y6O4%0j0j6u6(8$7_8^8)6n0L8i0X9j0|7g9m0F7l9p9E9G918i0x4*936F5`367`3`0|8t1%8w9e5K0|9F9%740R9Q8?7d8B045q4J4L4N4P7B8J9O0I0F4J0D0Z9i9+6-048*9Da49t3T0p4B4w4gae0p4j1u0c4laj2R2M0I1$ag4j1A5f3k2E0!0P0f0I0O6:0G0N0|1m1o1q1s0l9w2^[email protected]}1ia(0G2b2x1daK1F372#3k1-1U1W1Y4u4haM2^adau7{9?5s9_1s8,859W8^4%4)4+3M6g4/1{8x4^4`a0a39b7v04569{8zbz5X5j66bf9^5u0z5w5y0#5A5C7Qa90|5M9T7{5R0%bD9V4f6O8U5F5o5$8YbT04bV869;5:2-5=b!7MbH8V6264bSbF6a048!3h9X416g6ibW9YbB6n6p0b8iaL8#9:8(8C6 b:7=8-cl8}ca7/cda47Cb 6|6U6W2*9a9r8/0|8k7^9Acj8E6?cAc38^cnbl9;89cv27cucBcp8f78b-cE9xchcp9I8g9L9qcL6OcNc+ci7|7~7z8GcR84048KcU7E7G0F7Ibyc{3kb(5G8Xb)67c@6#7Sc!8%6,8`cscoc|c:cK4ScM9092dgbA7.ccce9/dcdh6/7 cJbjbEcOc/cQd13McTb$c/cW8hcYc23t9ycG8s8u9$dodFbkc.cpdwc=djbd8Ic_9O8O7JcYb_5Z8Vd55G8Zdtc45.a7dzb#dk9s0|0m9Oc%9ndSdEc09*d8a59-b-0xcfdWdh9!9oc*2Kbm9)9Oe8e64%9SdT3:debu8~c85^dm0Dbu959799d0dH8M9g4|d+a49k7hc(ef8Z0j8=db9z9;bJ5t9`ct9|eI0|9~a0a2eHe69B8+b-dM37ac4q2L4v2Las4i0(0*0,04.