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 :
-
valeur
est une valeur quelconque. Cela peut être un entier, une chaîne de caractère, obtenu en effectuant un calcul à l'aide deelement
ou sans rapport avec ce dernier..., -
element
prend les différentes valeurs présentes dansiterable
, -
iterable
est un objet que Python peut parcourir. Ce peut ĂŞtre une liste, un tuple, un dictionnaire, un objet de typerange
...
Exemples
-
Les entiers entre
0
et4
:>>> [x for x in range(5)] [0, 1, 2, 3, 4]
-
Les entiers pairs entre
0
et8
:>>> [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
0
et10
(inclus l'un et l'autre) - les entiers entre
-10
et10
(inclus l'un et l'autre) - les entiers pairs entre
-10
et10
(inclus l'un et l'autre) - les multiples de 3 entre
-30
et30
(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
,element
etiterable
répondent aux même spécifications que dans la version de base,condition
est une expression renvoyant un booléen (True
ouFalse
).
Exemples
-
Les entiers pairs entre
0
et10
:>>> [x for x in range(11) if x % 2 == 0] [0, 2, 4, 6, 8, 10]
-
Les notes comprises entre
12
et14
(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
fleurs
est untuple
mais 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 de4
caractè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 deTrue
quenombres
compte 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 denombres
sont infĂ©rieurs ou Ă©gaux Ă10
-
[True for x in nombres if x % 2 == 0]
renvoie une liste autant de foisTrue
quenombres
compte 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_points
aléatoires, tous dans le carré décrit ci-dessus. Cette liste est nomméepoints
et chaque point est représenté par ses coordonnées. Par exemple[(-0.5313, 0.0936), (0.9638, 0.3577), ...]
. -
une fonction
distance_origine
prenant en argument les coordonnéesx
ety
d'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)