Listes en compréhension
I. Premiers tableaux en compréhension⚓︎
Un tableau peut s'initialiser avec des éléments par défaut de plusieurs manières.
En voici deux :
>>> tableau = [0, 0, 0, 0]
>>> tableau = [0] * 4
Le langage Python permet une autre manière pour créer des tableaux : il s'agit de la construction par compréhension.
Cela permet de créer des tableaux que nous n'aurions pas su créer avec la méthode précédente. Par exemple, comment créer le tableaux contenant les 1000 premiers carrés : 1, 4, 9, 16, 25 etc ? Nous allons étudier omment procéder dans ce cours.
Le code suivant permet également de créer un tableau de 4 éléments initialisés à 0. C'est une création de tableau par compréhension. on dit aussi que le tableau est écrit en compréhension
>>> tableau = [0 for i in range(4)]
>>> tableau
[0, 0, 0, 0]
tableau = [0]*4
for i in range(4):
tableau[i] = i
tableau = [i for i in range(4)]
Question
tableau = [i for i in range(5, 15)]
-
tableau = [5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15]
-
tableau = [i, i, i, i, i, i, i, i, i, i]
-
tableau = [0, 0, 0, 0, 0, 0, 0, 0, 0]
-
tableau = [5, 6, 7, 8, 9, 10, 11, 12, 13, 14]
- La valeur 15 est exclue.
- i prend les valeurs de l'intervalle.
- La valeur n'est pas contante.
- i prend tour à tour les valeurs de 5 jusqu'à 14.
Question
Ecrire en compréhension la liste [5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5]
qui contient 20 fois l'entier 5.
Question
Compléter le script ci-dessous :
Solution
# un tableau cents en compréhension qui contient 10 entiers 100.
cents = [100 for k in range(10)]
# un tableau entiers en compréhension qui contient les 10 entiers entre 1 et 10 compris.
entiers = [k for k in range(1, 11)]
On peut aussi utiliser des chaînes de caractères :
Testez
Exécuter le script ci-dessous :
# Tests
(insensible à la casse)(Ctrl+I)
(Ctrl+Clic pour inverser les colonnes)
Question
Ecrire en compréhension : ['NSI-1', 'NSI-2', 'NSI-3', 'NSI-4', 'NSI-5', 'NSI-6', 'NSI-7', 'NSI-8', 'NSI-9', 'NSI-10']
# Tests
(insensible à la casse)(Ctrl+I)
(Ctrl+Clic pour inverser les colonnes)
Solution
mon_tab = ["NSI-"+ str(i) for i in range(1, 11)]
print(mon_tab)
Quelques exemples⚓︎
Question
Compléter ci dessous le script : Ecrire en compréhension lst3
qui donne la liste de la somme des éléments de [2, 3, 1, 5] et de [4, 1, 7, 0] qui sont de même taille.
On doit obtenir : [6, 4, 8, 5]
# Tests
(insensible à la casse)(Ctrl+I)
(Ctrl+Clic pour inverser les colonnes)
Solution
lst1 = [2, 3, 1, 5]
lst2 = [4, 1, 7, 0]
lst3 = [lst1[p] + lst2[p] for p in range(len(lst1))]
print(lst3)
Question
Répondre sur papier.
Donner les listes lst1, lst2, lst4, lst6 et lst7
lst1 = [3 for i in range(4)]
lst2 = [4-i for i in range(3)]
lst3 = [1, 2, 3]
lst4 = [lst3[i]**2 for i in range(len(lst3))]
lst5 = ["a","b","c"]
lst6 = [lst5[i]*2 for i in range(len(lst5))]
lst7 = [elem*2 for elem in lst5]
Solution
lst1 = [3, 3, 3, 3]
lst2 = [4, 3, 2]
lst4 = [1, 4, 9]
lst6 = ['aa', 'bb', 'cc']
lst7 = ['aa', 'bb', 'cc']
II. Utilisation plus élaborée des tableaux en compréhension⚓︎
Grâce à la construction par compréhension, il est possible d'appliquer un traitement (opération, fonction...) à chaque élément d'un tableau.
Testez
Exécuter le script ci-dessous :
# Tests
(insensible à la casse)(Ctrl+I)
(Ctrl+Clic pour inverser les colonnes)
Question
double = [i * 2 for i in range(10)]
-
double = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
-
double = [2, 3, 4, 5, 6, 7, 8, 9, 10, 11]
-
double = [0, 2, 4, 6, 8, 10, 12, 14, 16, 18]
-
double = [4, 8, 12, 16]
- Un traitement est appliqué aux valeurs prises par i.
- Le mauvais traitement est appliqué.
- le tableau est composé du double de chaque valeur de l'intervalle [0,9]
- Le tableau double doit contenir autant d'éléments que le tableau d'origine.
III. Appliquer un filtre⚓︎
La construction par compréhension permet d'appliquer un filtre à une structure de données de départ, afin de ne garder que certains éléments. On utilise pour cela une condition précédée du mot-clé if
.
On peut ainsi créer un tableau qui ne conserve que les nombres pairs d'un tableau initial.
>>> tableau = [0, 1, 6, 5, 4, 11, 12, 23, 26]
>>> pairs = [p for p in tableau if p%2 == 0]
>>> pairs
[0, 6, 4, 12, 26]
Question
tableau = [i for i in range(5, 15)]
nouveau_tableau = [j for j in tableau if j < 10]
-
nouveau_tableau = [5, 6, 7, 8, 9, 10, 11, 12, 13, 14]
-
nouveau_tableau = [5, 6, 7, 8, 9]
-
nouveau_tableau = [9, 8, 7, 6, 5]
-
nouveau_tableau = [10, 11, 12, 13, 14]
- La condition entraine la sélection de certaines valeurs.
- on sélectionne tous les éléments du tableau inférieurs à 10.
- Les éléments conservent l'ordre dans lequel il se trouvent dans le tableau initial.
- La condition indique les éléments qui sont conservés.
Question
Créer en compréhension la liste des carrés des nombres de la liste nombres
qui sont négatifs.
Question
Compléter le script ci-dessous :
# Tests
(insensible à la casse)(Ctrl+I)
(Ctrl+Clic pour inverser les colonnes)
Solution
# un tableau positifs en compréhension qui contient
# les nombres réels strictement positifs du tableau nombres
nombres = [1, 0, -2, 9, -5, 4, -7, 5, -8]
positifs = [k for k in nombres if k > 0]
# un tableau voyelle_phrase en compréhension qui ne contient que les voyelles
# contenues dans la chaine de caractère phrase
phrase = "je ne suis pas sans voix !"
VOYELLES = "aeiouy"
voyelle_phrase = [caractere for caractere in phrase if caractere in VOYELLES]
IV. Les tableaux de tableaux⚓︎
Pour construire un tableau de tableaux de même longueurs, on peut utiliser des compréhensions imbriquées.
Dans les exemples qui suivent nous appelerons matrice
notre tableau de tableaux.
>>> matrice = [[k for k in range(4)] for j in range(3)]
>>> matrice
[[0, 1, 2, 3], [0, 1, 2, 3], [0, 1, 2, 3]]
Pour bien visualiser le tableau matrice
que nous venons de créer, nous pouvons l'écrire de la façon suivante :
matrice = [ [0, 1, 2, 3],
[0, 1, 2, 3],
[0, 1, 2, 3] ]
matrice
correspond donc à une "ligne".
On peut considérer que matrice
a quatre "colonnes". Par exemple la première colonne (de rang 0) est [0, 0, 0]
, et la dernière est [3, 3, 3]
.
💡 Il est possible d'extraire une ligne de matrice
.
>>> ligne_0 = matrice[0]
>>> ligne_0
[0, 1, 2, 3]
💡 Il est possible d'extraire une colonne de matrice
.
>>> colonne_2 = [ligne[2] for ligne in matrice]
>>> colonne_2
[2, 2, 2]
Question
matrice = [[j for i in range(4)] for j in range(4)]
-
matrice = [[0, 1, 2, 3], [4, 5, 6, 7], [8, 9, 10, 11], [12, 13, 14, 15]]
-
matrice = [[0, 0, 0, 0], [1, 1, 1, 1], [2, 2, 2, 2], [3, 3, 3, 3]]
-
matrice = [[0, 1, 2, 3], [0, 1, 2, 3], [0, 1, 2, 3], [0, 1, 2, 3]]
-
matrice = [0, 1, 2, 3]
- La valeur j est constante pour chaque ligne.
- La valeur j prend la valeur 0 pour la première ligne, puis 1, etc.
- La valeur j est constante pour chaque ligne.
- Les constructions imbriquées engendrent un tableau de tableaux.
Question
Créer en compréhension la matrice [[0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0]]
Question
Compléter le script ci-dessous :
# Tests
(insensible à la casse)(Ctrl+I)
(Ctrl+Clic pour inverser les colonnes)
Solution
# un tableau matrice_carre_10 en compréhension, matrice 10x10
# dont chaque ligne contient les entiers de 1 à 10.
matrice_carre_10 = [[k for k in range(1, 11)] for j in range(10)]
# un tableau ligne_5 en compréhension qui contient la colonne 5 (située à l'indice 4)
# de la matrice matrice_carre_10
colonne_5 = [ligne[4] for ligne in matrice_carre_10]
# un tableau diagonale en compréhension qui contient la colonne 1ère colonne de la 1ère ligne,
# la 2ème colonne de la 2ème ligne.... de la matrice carrée matrice_carre_10
diagonale = [matrice_carre_10[i][i] for i in range(len(matrice_carre_10))]
Question
Compléter le script ci-dessous :
# Tests
(insensible à la casse)(Ctrl+I)
(Ctrl+Clic pour inverser les colonnes)
V. Exercice⚓︎
π à 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)
On demande d'extraire la liste des points situés dans le cercle à l'aide d'une liste en compréhension.
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
.
👉 On a donc 2 * random()
qui est compris entre 0
et 2
👉 On en déduit que 2 * random() - 1
est compris entre -1
et 1
.
# Tests
(insensible à la casse)(Ctrl+I)
(Ctrl+Clic pour inverser les colonnes)
Solution
Pour ne pas surcharger le site, nous avons choisi ici nb_points = 1000
. Chez vous, sur votre prpre éditeur Python, vous pouvez tester avec nb_points = 100_000
, pour obtenir une meilleure précision.
from math import sqrt
from random import random
nb_points = 1000
points = [(2 * random() - 1, 2 * random() - 1) for _ in range(nb_points)]
def distance_origine(x, y):
return sqrt(x * x + y * y)
proches = [p for p in points if distance_origine(p[0], p[1]) <= 1]
approximation = 4 * len(proches) / nb_points
print("Pi est environ égal à : ", approximation)
VI Crédits⚓︎
Pierre Marquestaut, Nicolas Revéret et Mireille Coilhac
# Tests
(insensible à la casse)(Ctrl+I)
(Ctrl+Clic pour inverser les colonnes)