import csv
def index_tableau(nomDeFichier):
tab = []
with open(nomDeFichier,'r',encoding='utf-8') as f:
lecteur = csv.reader(f,delimiter=',')
for row in lecteur:
tab.append(row)
return tab
tab = index_tableau("countries.csv") # construction du tableau de tableaux
print(tab) # affichage tableau entier
print(tab[2]) # 3ème ligne
print(tab[51]) # 52ème ligne
import csv
def index_dico(nomDeFichier):
tab=[]
with open(nomDeFichier,'r',encoding='utf-8') as f:
lecteur=csv.DictReader(f,delimiter=',')
for row in lecteur:
tab.append(dict(row))
return tab
tab = index_dico("countries.csv") # construction du tableau de dictionnaires
print(tab) # affichage tableau entier
print(tab[2]) # 3ème ligne
print(tab[51]) # 52ème ligne
Dans la suite, le code de la fonction d'indexation ne sera plus indiqué. Le tableau de dictionnaires porte le nom de tabDico.
def recherche(donnees,clef_rech,val_rech,clef_aff):
'''
donnees : tableau de dictionnaires contenant les données
clef_rech : clef à laquelle appartient la valeur recherchée
val_rech : valeur recherchée
clef_aff : clef de la valeur que l'on veut afficher
'''
for element in donnees:
if element[clef_rech] == val_rech:
return element[clef_aff]
# Monnaie utilisée au Botswana :
print(recherche(tabDico, "name", "Botswana", "currency_name"))
# Superficie de Hong-Kong :
print(recherche(tabDico, "name", "Hong Kong", "area"))
# Code ISO de la Micronésie :
print(recherche(tabDico, "name", "Micronesia", "iso"))
# Pays dont le code ISO est CR :
print(recherche(tabDico, "iso", "CR", "name"))
# Pays dont la monnaie est l'euro :
print(recherche(tabDico, "currency_name", "Euro", "name"))
print(recherche(tabDico, "currency_code", "EUR", "name")) # autre possibilité
→ n'affiche que le premier pays dans le tableau dont la monnaie est l'euro ( Andorre ), et pas tous les autres...
Solution :
def recherche2(donnees, clef_rech, eletrech, clef_aff):
return [r[clef_aff] for r in donnees if r[clef_rech] == eletrech]
print(recherche2(tabDico,'currency_code','EUR','name'))
def rechercheA(donnees):
return [p['name'] for p in donnees if int(p['population'])<100000 and p['continent'] == 'EU']
def rechercheB(donnees):
return [p['name'] for p in donnees if float(p['area'])>9000000 and p['currency_code'] == 'USD']
print(rechercheA(tabDico))
print(rechercheB(tabDico))
# noms des pays dont la population est de moins de 1000 habitants, ou dont la superficie est supérieure à 10000000
[p['name'] for p in tabDico if int(p['population'])<1000 or float(p['area'])>10000000)]
def coherenceB(donnees):
for pays in donnees:
if pays['continent'] not in ['AF', 'AS', 'EU', 'NA', 'OC', 'SA']:
print('Incohérence pour', pays)
print(coherenceB(tabDico))
tabDico.sort()
>>> TypeError: '<' not supported between instances of 'dict' and 'dict'
def cle_population(p):
return p['population']
tabDico = index_dico("countries.csv")
tabDico.sort(key = cle_population)
print(tabDico[0], tabDico[1], tabDico[2])
→ le tableau de dictionnaires n'est pas classé par ordre de valeur de population, car cette donnée est en fait une chaîne de caractères (str) dans les dictionnaires : le tri ne se fait donc pas selon
l'ordre numérique, mais selon l'ordre lexicographique, c'est à dire celui des caractères, et pas celui des nombres.
Selon cet ordre, on aura alors par exemple: "232" > "12345689", car le caractère "2" suit le caractère "1" dans l'ordre lexicographique; selon l'ordre numérique, on aurait bien entendu : 232 < 12345689...
Il faut donc convertir les données de population en nombre entier :
def cle_population(p):
return int(p['population']) # et là, ça fonctionne !
tabDico = index_dico("countries.csv")
tabDico.sort(key = cle_population)
print(tabDico[0], tabDico[1], tabDico[2])
Pour afficher les noms des pays de la zone Euro par ordre de population croissante :
def cle_population(p):
return int(p['population'])
tabDico = index_dico("countries.csv")
tabEuro = [p for p in tabDico if p['currency_code'] == "EUR"] # tableau des dictionnaires des pays de la zone Euro
tabEuro.sort(key = cle_population)
print(tabEuro)
Pour afficher les noms des pays de la zone Euro par ordre de superficie croissante :
def cle_superficie(p):
return float(p['area']) # la superficie est un nombre flottant
tabDico = index_dico("countries.csv")
tabEuro = [p for p in tabDico if p['currency_code'] == "EUR"] # tableau des dictionnaires des pays de la zone Euro
tabEuro.sort(key = cle_superficie)
print(tabEuro)
| acteur | film_id | titre | anSortie | duree | vo | genres | recette |
|-----------------|-----------|-------------|------------|---------|----|----------|-----------|
| Hugo Haas | 212 |Tête de thon | 1998 | 120 | fr | comédie | 137000 |
| Bill Waterson | 212 |Tête de thon | 1998 | 120 | fr | comédie | 137000 |
|Xavier Le Noëllec| 131 | Paddle Life | 2020 | 105 |bzh | aventure | 452000 |
def fusion(table1, cle1, table2, cle2):
fusion = []
for element1 in table1: # pour chaque dictionnaire dans la première table,
for element2 in table2: # pour chaque dictionnaire dans la deuxième table,
if element1[cle1] == element2[cle2]: # si les deux valeurs correspondant à cle1 et cle2 sont les mêmes dans les deux tables,
element_fusion = element1 # alors on a trouvé la colonne de données communes aux deux tables.
for clef in element2: # on parcourt alors les colonnes de la deuxième table,
element_fusion[clef] = element2[clef] # et on stocke chacune de ces colonnes dans le dictionnaire de fusion.
fusion.append(element_fusion) # on ajoute le dictionnaire à la table fusionnée.
return fusion
countries = index_dico("countries.csv")
cities = index_dico("cities.csv")
f = fusion(countries, "capital", cities, "id")
print(f[0])
>>> {'iso': 'AD', 'name': 'Andorra', 'area': '468.0', 'population': '84000', 'continent': 'EU', 'currency_code': 'EUR', 'currency_name': 'Euro', 'capital': '6', 'id': '6', 'nameCity': 'Andorra la Vella', 'latitude': '42.50779', 'longitude': '1.52109', 'country': 'AD', 'populationCity': '20430'}
→ la donnée des colonnes communes aux deux tables ("id" et "capital" ) se retrouve deux fois dans la table fusionnée : il ne faut donc stocker cette information qu'une seule fois :
def fusion(table1, cle1, table2, cle2):
fusion = []
for element1 in table1:
for element2 in table2:
if element1[cle1] == element2[cle2]:
element_fusion = element1
for clef in element2:
if clef != cle2: # si la colonne n'est pas celle correspondant à cle2,
element_fusion[clef] = element2[clef] # alors seulement on stocke cette colonne dans le dictionnaire fusion.
fusion.append(element_fusion)
return fusion
countries = index_dico("countries.csv")
cities = index_dico("cities.csv")
f = fusion(countries, "capital", cities, "id")
print(f[0])
>>> {'iso': 'AD', 'name': 'Andorra', 'area': '468.0', 'population': '84000', 'continent': 'EU', 'currency_code': 'EUR', 'currency_name': 'Euro', 'capital': '6', 'nameCity': 'Andorra la Vella', 'latitude': '42.50779', 'longitude': '1.52109', 'country': 'AD', 'populationCity': '20430'}
→ la colonne "id" a bien été supprimée.
Les fonctions de recherche peuvent être alors utilisées, comme pour une table non fusionnée :
#Afficher toutes les capitales dans lesquelles on peut dépenser des Euros :
print([p['nameCity'] for p in f if p['currency_code'] == 'EUR'])
# Afficher le nom des pays dont la capitale a moins de 100 000 habitants :
print([p['name'] for p in f if int(p['populationCity']) < 100000])
# Afficher le nom des pays dont la capitale est située entre les deux tropiques (de latitudes -23.436° et +23.436°)
print([p['name'] for p in f if -23.436 < float(p['latitude']) < 23.436])