Les compréhensions
Lorsqu'on écrit des programmes, on va chercher à obtenir un code le plus court possible (en utilisant des fonctions réutilisables, des fonctions récursives,...)
Lorsque l'on veut créer automatiquement (par exemple avec des valeurs prises au hasard) une collection (une liste, un dictionnaire, un set), on utlise les compréhensions
C'est une façon d'écrire son code (syntaxe) qui va le raccourcir.
Cela permet également de le rendre un peu plus lisible.
Ces collections sont des itérables.
Collections : à savoir
Les chaines, les listes, les dictionnaires, les tuples, les sets sont des collections parce qu'elles permettent de stocker une collection d'éléments.
Itérables : à savoir
Un itérable est un objet que l'on peut parcourir donc une liste, un dictionnaire...
Compréhension de liste
Dans cet exmple, on génère la liste des 10 premiers nombres entiers :
# avec une boucle for
liste_for = []
for i in range(1,11):
liste_for.append(i)
print(liste_for)
# avec une compréhension de liste
liste = [i for i in range(1,11)]
print(liste)
Compréhension de liste avec une condition
Dans cet exmeple, on génère la liste des nombres pairs parmi les 10 premiers nombres entiers :
# avec une boucle for
liste2_for = []
for i in range(1,11):
if i%2 == 0:
liste2_for.append(i)
print(liste2_for)
# avec une compréhension de liste
liste2 = [i for i in range(1,11) if i%2 == 0]
print(liste2)
Compréhension de dictionnaire
Lors de la création d'une liste, nous ajoutons un seul élément à la fois lors de l'itération.
Pour les dictionnaires, la méthode reste la même mais c'est un peu plus compliqué, car nous devons ajouter deux éléments à chaque itération (une clef et une valeur)
Premier cas : générer un dictionnaire à partir d'un seul élément de l'itérable
Dans notre exemple, nous allons générer automatiquement la valeur. Mais cela est tout à fait possible aussi avec la clef.
Nous souhaitons, à partir d'une liste de candidats, déterminer au hasard s'ils ont gagné créer un dictionnaire contenant :
- un prénom comme clef
- un statut de gagnant (1) ou de perdant (0) déterminé au hasard comme valeur (à l'aide de random.randint(0,1))
# tirage au sort de candidats
import random
candidats = ['Hugo','Mathilde','Karima','Célestine','Norédine','Maxime','Soledad','Piotr']
dict_selection = {prenom:random.randint(0,1) for prenom in candidats}
print(dict_selection)
# on peut ensuite afficher la liste des gagnants
for clef,valeur in dict_selection.items():
if valeur == 1:
print(clef)
...Nous sommes à fond dans les listes de compréhension et, pour afficher les gagnants, on a ressorti une boucle for comme avant ?
Effectivement, nous pouvons faire mieux. Reprenons le code et améliorons-le :
# tirage au sort de candidats
import random
candidats = ['Hugo','Mathilde','Karima','Célestine','Norédine','Maxime','Soledad','Piotr']
dict_selection = {prenom:random.randint(0,1) for prenom in candidats}
# on peut ensuite afficher la liste des gagnants (avec une compréhension de dictionnaires cette fois !!!)
dict_gagnant={prenom:statut for (prenom, statut) in dict_selection.items() if statut ==1}
print(dict_gagnant)
Comprendre cet ajout à notre programme
- nous créons un nouveau dictionnaire dict_selection
- nous le peuplons avec le prénom du candidat comme clef et son statut comme valeur SI il est gagnant donc SI son status est à 1
Second cas : générer un dictionnaire à partir des deux éléments de l'itérable
Ici, nous souhaitons stocker dans des dictionnaires les carrés et les cubes des nombres entiers entre 1 et 50.
dict_carres = {nombre:nombre**2 for nombre in range(1,51)}
dict_cubes = {nombre:nombre**3 for nombre in range(1,51)}
# affiche le carré et le cube de 11
print(dict_carres[11])
print(dict_cubes[11])
dict_carres_pairs = {nombre:nombre**2 for nombre in range(1,51) if nombre%2 == 0}
print(dict_carres_pairs)