Les listes en compréhension
Sans condition
Créer une liste contenant de nombreux éléments peut se faire à l'aide d'une boucle for.
Le script ci-dessous crée par exemple la liste des éléments entre 0 et 100 :
entiers = []
for x in range(101):
entiers.append(x)
Syntaxe pour des listes en compréhension
Python propose une autre façon de créer la même liste : la liste en compréhension.
Le schéma général est [valeur for element in iterable] dans lequel :
-
valeurest une valeur quelconque. Cela peut être un entier, une chaîne de caractère, obtenu en effectuant un calcul à l'aide deelementou sans rapport avec ce dernier..., -
elementprend les différentes valeurs présentes dansiterable, -
iterableest un objet que Python peut parcourir. Ce peut ĂŞtre une liste, un tuple, un dictionnaire, un objet de typerange...
Exemples
-
Les entiers entre
0et4:>>> [x for x in range(5)] [0, 1, 2, 3, 4] -
Les entiers pairs entre
0et8:>>> [2 * x for x in range(5)] [0, 2, 4, 6, 8] -
La liste des lettres de
"python":>>> [lettre for lettre in "python"] ['p', 'y', 't', 'h', 'o', 'n'] -
La liste des lettres de
"python"en majuscule :>>> [lettre.upper() for lettre in "python"] ['P', 'Y', 'T', 'H', 'O', 'N']
Activité 1 - Comment faire ?
On souhaite obtenir la liste des entiers entre 3 (inclus) et 103 (inclus).
Quelles instructions renvoient cette liste ?
-
[k in range(3, 104)] -
[k for k in range(3, 103)] -
[k for k in range(3, 104)] -
[k + 3 for k in range(101)] -
[k // 2 for k in range(6, 208)]
[k in range(3, 104)]est syntaxiquement incorrect, la structure attendue est[valeur for element in iterable][k for k in range(3, 103)]gĂ©nère[3, 4, ..., 102]. Il manque la dernière valeur[k for k in range(3, 104)][k + 3 for k in range(101)][k // 2 for k in range(6, 208)]pourrait fonctionner si l'on utilisait un pas Ă©gal Ă2. Ici on gĂ©nère la liste[3, 3, 4, 4, ..., 103, 103]
Activité 2 - Dans un terminal
Utilisez le terminal ci-dessous afin de créer les listes suivantes :
- les entiers entre
0et10(inclus l'un et l'autre) - les entiers entre
-10et10(inclus l'un et l'autre) - les entiers pairs entre
-10et10(inclus l'un et l'autre) - les multiples de 3 entre
-30et30(inclus l'un et l'autre) - vingt fois la valeur
None - la liste des caractères de "Hello World"
- la liste des caractères de "Hello World" en minuscule (Python considère que la minuscule de
' 'est' '!)
Solution
[k for k in range(0, 11)][k for k in range(-10, 11)][k for k in range(-10, 11, 2)][k for k in range(-30, 31, 3)][None for _ in range(20)]. La variable d'itération n'étant pas utilisée, on peut la nommer_[caractere for caractere in "Hello World"][caractere.lower() for caractere in "Hello World"]
Activité 3 - Générer l'alphabet
On cherche dans cet exercice à créer la liste de toutes les lettres de l'alphabet en majuscule. Plusieurs options s'offrent à nous :
- écrire la liste à la main. C'est fastidieux et nous ne sommes pas à l'abri d'un oubli ou d'une erreur...
- s'appuyer sur la table ASCII qui contient déjà tous ces caractères.
On en fournit ci-dessous un extrait :
... |
"A" |
"B" |
"C" |
... |
"Y" |
"Z" |
"[" |
... |
Comme on peut le voir, les caractères de l'alphabet en majuscule sont tous à la suite dans la table. Chacun est associé à un code (non donné dans le tableau). Ces codes sont des entiers consécutifs (le code de "B" est égal à celui de "A" augmenté de 1...).
La fonction ord de Python permet d'obtenir le code d'un caractère présent dans la table ASCII. Par exemple ord("@") renvoie 64.
La fonction chr fait l'opération réciproque : elle prend en argument un entier et renvoie le caractère correspondant de la table ASCII. Ainsi : chr(64) renvoie '@'.
Utilisez le terminal ci-dessous afin de créer la liste contenant toutes les lettres de l'alphabet en majuscule.
On rajoute les contraintes suivantes :
-
il est interdit d'écrire directement l'alphabet : vous devez utiliser une liste en compréhension ;
-
afin de corser la difficulté, on interdit de plus d'utiliser des chiffres autres que le
1! Il est donc interdit de saisir « en dur » le code du"A"et celui du"Z". Rien n'empêche par contre d'utiliserord("A")...
Solution
On peut faire [chr(k) for k in range(ord("A"), ord("Z") + 1)]. On est ainsi sûr de n'oublier aucune lettre !
Sans la contrainte sur les caractères numériques, on peut faire [chr(k) for k in range(ord("A"), ord("A") + 26)]
Avec condition
Listes en compréhension conditionnelles
Les listes en compréhension sont encore plus intéressantes lorsque l'on rajoute des conditions. La structure générale devient alors [valeur for element in iterable if condition] :
valeur,elementetiterablerépondent aux même spécifications que dans la version de base,conditionest une expression renvoyant un booléen (TrueouFalse).
Exemples
-
Les entiers pairs entre
0et10:>>> [x for x in range(11) if x % 2 == 0] [0, 2, 4, 6, 8, 10] -
Les notes comprises entre
12et14(inclus l'un et l'autre):>>> notes = [17, 11, 13, 14, 10, 19, 13] >>> [x for x in notes if 12 <= x <= 14] [13, 14, 13] -
Les fleurs débutants par le caractère
"A":>>> fleurs = ("Arum", "Rose", "Azalée", "aster") >>> [f for f in fleurs if f[0] == "A"] ["Arum", "Azalée"]Remarque
Notez que
fleursest untuplemais que l'on crée bien une liste en compréhension.
Il est aussi possible d'utiliser des conditions complexes :
-
Les nombres pairs et infĂ©rieurs Ă
100:>>> nombres = [353, 108, 98, 101, 79, 93] >>> [x for x in nombres if x % 2 == 0 and x <= 100] [98] -
Les fleurs débutants par
"A"ou dont le nom comporte moins de4caractères :>>> fleurs = ("Arum", "Rose", "Azalée", "aster") >>> [f for f in fleurs if f[0] == "A" or len(f) <= 4] ["Arum", "Rose", "Azalée"]
Activité 4 - Qui fait quoi ?
On considère la liste nombres définie par nombres = [k for k in range(-10, 11)].
Cocher les informations correctes.
-
[x for x in nombres if x != 11]renvoie une copie denombres -
[x for x in nombres if x > 10]renvoie une liste vide -
[True for x in nombres if x % 2 == 0]renvoie une liste d'autant deTruequenombrescompte de nombres pairs -
[1 / x for x in nombres]renvoie la liste des inverses des valeurs denombres
[x for x in nombres if x != 11]renvoie bien une copie denombres[x for x in nombres if x > 10]renvoie une liste vide car tous les Ă©lĂ©ments denombressont infĂ©rieurs ou Ă©gaux Ă10[True for x in nombres if x % 2 == 0]renvoie une liste autant de foisTruequenombrescompte de nombres pairs[1 / x for x in nombres]renvoie une erreur car on demande Ă Python de diviser par0
Activité 5 - Filtrer des nombres aléatoires
Les instructions suivantes permettent de générer 1 000 nombres entiers aléatoires de -100 à 100 :
from random import randrange
nombres = [randrange(-100, 101) for _ in range(1000)]
Compléter le code ci-dessous afin de filtrer cette liste comme demandée.
Au bout de 10 essais infructueux, le corrigé vous est proposé.
Activité 6 - π à Monte-Carlo
La méthode de Monte-Carlo est un ensemble de méthodes algorithmiques visant à déterminer la valeur approchée d'une constante en utilisant des procédés aléatoires.
On peut utiliser cette méthode afin de déterminer une valeur approchée de \(\pi\). L'idée est la suivante :
- on considère un carré de \(2\) unités de côtés. Son aire vaut donc \(4\) ;
- on considère un disque de rayon \(1\) centré au centre du carré. Son aire vaut donc \(\pi \times 1^2=\pi\) ;
- on génère un grand nombre de points aléatoires répartis de façon uniforme dans le carré.
Il reste alors à compter le nombre de points à l'intérieur du disque. On peut montrer que leur fréquence tend vers \(\frac{\pi}{4}\) quand le nombre de points aléatoires devient très grand.
Une valeur approchée de \(\pi\) est donc :
On observe ci-dessous le carré de départ ainsi que de nombreux points. On a représenté de couleur différente ceux qui sont dans le cercle et ceux qui n'y sont pas.
On se donne donc :
-
une liste de
nb_pointsaléatoires, tous dans le carré décrit ci-dessus. Cette liste est nomméepointset chaque point est représenté par ses coordonnées. Par exemple[(-0.5313, 0.0936), (0.9638, 0.3577), ...]. -
une fonction
distance_origineprenant en argument les coordonnéesxetyd'un point et renvoyant sa distance à l'origine du repère (et donc au centre du cercle)
La fonction random
Le module random de Python propose une fonction random qui génère des nombres aléatoires uniformément répartis entre 0 et 1.
Donc 2 * random() est compris entre 0 et 2 et 2 * random() - 1 entre -1 et 1.
On demande d'extraire la liste des points situés dans le cercle à l'aide d'une liste en compréhension.
Au bout de 10 essais infructueux, le corrigé vous est proposé.
# Tests (insensible Ă la casse)(Ctrl+I)
# Tests(insensible Ă la casse)(Ctrl+I)