Aller au contenu

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 :

Python
>>> 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

Python
>>> tableau = [0 for i in range(4)]
>>> tableau
[0, 0, 0, 0]
De la même façon, la boucle suivante :
Python
tableau = [0]*4
for i in range(4):
    tableau[i] = i
peut s'écrire :
Python
tableau = [i for i in range(4)]

Question
Python
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.

Puzzle

Question

Compléter le script ci-dessous :

###(Dés-)Active le code après la ligne # Tests (insensible à la casse)
(Ctrl+I)
Entrer ou sortir du mode "deux colonnes"
(Alt+: ; Ctrl pour inverser les colonnes)
Entrer ou sortir du mode "plein écran"
(Esc)
Tronquer ou non le feedback dans les terminaux (sortie standard & stacktrace / relancer le code pour appliquer)
Si activé, le texte copié dans le terminal est joint sur une seule ligne avant d'être copié dans le presse-papier
Évaluations restantes : 5/5

.128013.65038.9875kg[: r;)S/q(loy,b=ac15ud3t2_Pwevp-fh0mnR]is050A0H0C0v0S0p0T0h0w0p0v0T0T0u010C0S0J010406050T0z0O0O0v0i0r040l0q0p0z0.0q0P0h020v0O0J0j0h0Q0H0{0i0n0z0H0T050m0^0`0|0~0?0J04051t1m1w0m1t0?0A0S0I0$0(0*0,0(0P0e0z0v0e0H0K0J0r0C0M150h0M0S0e0M0p1Y0M0C0;050X0t0p0H1F0)0+011X1Z1#1Z0C1+1-1)0C0i1u1T0$110T0J0v0P0,0D011/1H010L0Z0H0P190H1)24262b1;2e1-2h0O2j040a0h0F0i0q0J0q0T0S14160V220i0i0H0w2E1m2l0P1u0m1T2Q1~201 1*0A2n1I0S0P2g2B1)1C1E0%1:2!2$0P0q2*1)0J2J1u2O2Q2`0@25162,2c2:0i0{0p1)0v1W2J0L0,030E0E0w2;0H1#2/0q0K0y0K0x0;0x1m0v2{2~0=2}2m301;323436380H3a013c3e3g3i2%3l0K29040D3r3t262Q2@0H2Q2*2T0A202Y3y0,3f0V2)1D1u3V2_3u2N3:3)3W3w160S0A0,3d2O3M3o1u373`3|3I0V3K2:3 2a2r0H443?473k3m403R3^2Z010P0;0w2g0C1l1n3u0h4k3%010q0;0u3;3T4v2O4l0:040f4C2P4w1G1;0O0S3p0N0N4K044E2~4l0d0;0L0q0i4U4W3x4N0,4n040d4(4M2-4y0G0;2#4:4F4x0P0t0;0i261O4U4;2c4H0o534{4+014P4R584X4x4H0k0R4U0?4t3T4k43013}2~3M3O05423{5q453h2#3L3m290h4b4d3J5B485D1)0m3s543z0;4q0S0H0i4s2`4)2 5a4z044B5m2P5Y4G0;4J5(3/4*4=4-4/5.5*4x4Z044#4%5@5P4,0;5?5X5 4?4^0P4`5f5a4}4 510H5e5:550;575.645c043q6k594=4H0s686g4O4Q6n6o2|6q6h045i5k530m3?3U2^1m3Y1m0C3!6N2W2R0v1,3@0m3Y1s5/5Z4=2J0O0E0L0v0d0H0E0M0B0;1e1g1i1k0h0g6G1A050M0D0h5p6$0|6?6:1f721j5v4l0M0H0v0V0i3i4Z3D3F03711h1j2a0.0C1-0,0F5U0{2/0C0h7f0;0c0b4j0m6}3v1t0F0)0h2G7k6?1x3v6W0W0Y0!04.
Solution
Python
# 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 :

###(Dés-)Active le code après la ligne # Tests (insensible à la casse)
(Ctrl+I)
Entrer ou sortir du mode "deux colonnes"
(Alt+: ; Ctrl pour inverser les colonnes)
Entrer ou sortir du mode "plein écran"
(Esc)
Tronquer ou non le feedback dans les terminaux (sortie standard & stacktrace / relancer le code pour appliquer)
Si activé, le texte copié dans le terminal est joint sur une seule ligne avant d'être copié dans le presse-papier

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']

###(Dés-)Active le code après la ligne # Tests (insensible à la casse)
(Ctrl+I)
Entrer ou sortir du mode "deux colonnes"
(Alt+: ; Ctrl pour inverser les colonnes)
Entrer ou sortir du mode "plein écran"
(Esc)
Tronquer ou non le feedback dans les terminaux (sortie standard & stacktrace / relancer le code pour appliquer)
Si activé, le texte copié dans le terminal est joint sur une seule ligne avant d'être copié dans le presse-papier

Solution
Python
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]

###(Dés-)Active le code après la ligne # Tests (insensible à la casse)
(Ctrl+I)
Entrer ou sortir du mode "deux colonnes"
(Alt+: ; Ctrl pour inverser les colonnes)
Entrer ou sortir du mode "plein écran"
(Esc)
Tronquer ou non le feedback dans les terminaux (sortie standard & stacktrace / relancer le code pour appliquer)
Si activé, le texte copié dans le terminal est joint sur une seule ligne avant d'être copié dans le presse-papier

Solution
Python
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

Python
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
Python
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 :

###(Dés-)Active le code après la ligne # Tests (insensible à la casse)
(Ctrl+I)
Entrer ou sortir du mode "deux colonnes"
(Alt+: ; Ctrl pour inverser les colonnes)
Entrer ou sortir du mode "plein écran"
(Esc)
Tronquer ou non le feedback dans les terminaux (sortie standard & stacktrace / relancer le code pour appliquer)
Si activé, le texte copié dans le terminal est joint sur une seule ligne avant d'être copié dans le presse-papier

Question
Python
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.
Question

Compléter pour obtenir la liste dizaines = [0, 10, 20, 30, 40, 50, 60, 70, 80, 90]

Puzzle

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.

Python
>>> 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
Python
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 nombresqui sont négatifs.

Puzzle

Question

Compléter le script ci-dessous :

###(Dés-)Active le code après la ligne # Tests (insensible à la casse)
(Ctrl+I)
Entrer ou sortir du mode "deux colonnes"
(Alt+: ; Ctrl pour inverser les colonnes)
Entrer ou sortir du mode "plein écran"
(Esc)
Tronquer ou non le feedback dans les terminaux (sortie standard & stacktrace / relancer le code pour appliquer)
Si activé, le texte copié dans le terminal est joint sur une seule ligne avant d'être copié dans le presse-papier

Solution
Python
# 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.

Python
>>> 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 :

Python
    matrice = [ [0, 1, 2, 3],
                [0, 1, 2, 3],
                [0, 1, 2, 3] ]         
👉 Chaque élément de 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.

Python
>>> ligne_0 = matrice[0]
>>> ligne_0
[0, 1, 2, 3]

💡 Il est possible d'extraire une colonne de matrice.

Python
>>> colonne_2 = [ligne[2] for ligne in matrice]
>>> colonne_2
[2, 2, 2]
Question
Python
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]]

Puzzle

Question

Compléter le script ci-dessous :

###(Dés-)Active le code après la ligne # Tests (insensible à la casse)
(Ctrl+I)
Entrer ou sortir du mode "deux colonnes"
(Alt+: ; Ctrl pour inverser les colonnes)
Entrer ou sortir du mode "plein écran"
(Esc)
Tronquer ou non le feedback dans les terminaux (sortie standard & stacktrace / relancer le code pour appliquer)
Si activé, le texte copié dans le terminal est joint sur une seule ligne avant d'être copié dans le presse-papier

Solution
Python
# 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 :

###(Dés-)Active le code après la ligne # Tests (insensible à la casse)
(Ctrl+I)
Entrer ou sortir du mode "deux colonnes"
(Alt+: ; Ctrl pour inverser les colonnes)
Entrer ou sortir du mode "plein écran"
(Esc)
Tronquer ou non le feedback dans les terminaux (sortie standard & stacktrace / relancer le code pour appliquer)
Si activé, le texte copié dans le terminal est joint sur une seule ligne avant d'être copié dans le presse-papier
Évaluations restantes : 2/2

.128073.9875.128013.65038.128161Eg[ r;)/(lo4,6b=ax5utP7e-h0mnkê:Séq.y1cd32à8_wvpfO9RA]is050S0C0z0v0+0o0,0i0R0o0v0,0,0u010z0+0!010406050,0y0G0G0v0j0P040L0p0o0y100p0H0i020v0G0!0k0i0(0C1a0j0N0y0C0,050m17191b1d150!04051I1B1L0m1I150S0+0Z0^0`0|0~0`0H0g0y0v0g0C0D0!0P0z0E1k0i0E0+0g0E0o1;0E0z13050:0t0o0C1U0{0}011:1=1@1=0z1}1 1{0z0j1J1,0^1g0,0!0v0H0~0U01211W010#0=0C0H1o0C1{2j2l2q232t1 2w0G2y040c0i0A0j0p0!0p0,0+1j1l0.2h0j0j0C0R2T1B2A0H1J0m1,2)2d2f2e1|0S2C1X0+0H2v2Q1{1R1T0_222?2^0H0p2|1{0!2Y1J2%2)39162k1l2~2r320j1a0o1{0v1/2Y0#0~030X0X0R330C1@310p0D0U0Q0D0Q130i0Q1B0v3a3d143c2B3f233h3j3l3n0C3p013r3t3v3x2_3A3C2o040i0U3I3K2l3M2%2=013R0v3k1J3m0E3o3q3s3u0.3#323%0D0T3F0T3-2$3L153;3P0~3@3_053{3}3X3 3!2@3$3B0D0q3F0q491C4b3N3e1V3Q0p3i3^3T3|3V3~3Z414o434q0x3F0x4v394c3d3=4g4F4k3Y403w4L3z4q0s3F0s4R4x4d4A4f4C3S3`3U3W4Z4n3y440B3F0B4,3/4T3O4/3?4;4E4?4G4^4m4K4{4q0W3F0W502(524z2 554D4h4j4H4l4J4#5d3C0%3F0%5i3:4U4e5n4=4i4@4I4!424%3C0Q0F135N5A5k4V565p5H5s5J4$440Q3E045#5R4y5T5o4X5r4_5c4p5M3)0Q3,0m3J4a515*5D4W584Y5b5u5;3D465%485_3.5j5}545 5G595I4`640Q4s5%4u695{6b4.5m6e5q5a5t5K5!4O5%4Q6o4w3/1M371B2|2,0S2f2;5D4!2{1S1J360C383L6p1J4!6U2B0+0S0~3s2%5!3T6#6%6w5Z4q3E0i2G0C6-5Y5v3D1{6o6r2r0I130.0#6W0i6c6s0#131%0z0X1R1$0X5^3b6~2312040n6W763g130?0z7n7i0~7k0l747o230p130D020g0z0k7y7u3?0t7q0+0,7s6D2(757J7k0K6W157Q6Z1l6,016(3d443)5G7#626x4q2o6=2x6^6i4M3(6|5`7J0Y3F0i7 7t5C540,0S13021x0p7G870y890k8b8d7W816!6$7$0X6)4q667+8k7-6/3C467;2H7?5:7^457`7Z3=847~7 0f0H2d0M200K0i7r0i8N0y2^8O7N0z202V1@7O1z0i2V0G0J2H0@0o1k1!0C0y0j1A7Y7X7h4U7,8m7(4q6l8q8y638A4s8w6@8l6_648~6}825m8F3*7 0i1f0j108M8$0+7e0U8Q0i8S208Z8W8$1k0z8O8#0M0o0M2H8J0@0,9w9y0@9A9C2v0z0@8Y3m0U1u8X9m0g1k3^208h7Y5*8`8n3C6z8 967@5L0D4O94907.9(8C7z0~9d9f0i0n0S02030T0%0k2v1/0v1i7 0S2N2S200V0ia40t0{0iad0ga60R0E0C7x8?8i7!8r8{2l444)4?8`978A4)9:9+8z9-ax497J9`9f7E8a7F8eaO0i0G0i0u0i0haV0Q0r0i0TaZ0q0*0r9Z8^8j6-9%0D4}ayataA9-4}aD8s6`a:aI9b2raK9{b19f0h0x0i0r0sb60Wa(a*6V3;9$8|3C5fa;9;8t0D5fa_6.6`bia}539c859eb2b20h0UaZaYa!0*0i0*bc6Ebeata.5xbjaE919-5xboa?44bMbs5la bv9{aMaPaN7G0i7a7c9U7f0n0Gap4Sar0ibfav6:5ObNa`6j5ObS9,5!b`bW8EbZb30qaZ0saZ0UbGaq9!bJa-bg3D5$9*b|8A5#2p6?bk6`cn2)3J8@bd8_bKch5@6+a=c06:7:cpbO9=3D7*9abtbY8G1m888acQ8ecSbH2(9#cyb^5M8p3mazcDc!co7=cHbl0Q8p69cvbIcxcgcZ3D8~c$cCaF5!93cGcl9-6k8C9{9^3?132@1R0R0C0X1a0w7Ia~7A130udgcM3Q7L042Fb=5D7k7mcedh4f7q7Odr547wdlbXdi040DdD3=0G0+5PcV8Db@0H6ycBcq6j9/d0bpdUd49fd670042Y0z8:0HdIds130hdA6sdy7Pa+dE7vd.d:7p040+d{7j130*d/dvdmdxd}0Hdadcded 0~7BdGecd7d}eg7kcc397Sdw01d$0#4Cd,6dd8et5m0p7}e7ew3gdo0j2l1%ej13dud@4Vdodqe4d^01dteg0Hd=eH040l0lel4x9!0m6Y6F6T6H6Q1B0z6Ke,2/2*0v1~e)0m6I1H8D5D2Y0G0X0#0v0Idc0E661t1v1x8#7Ve#1P050E9o7#e}1bf80,13f6fi1y1A3m5Dan0v0.0j3x705W03fh1wfo2p100z1 0~0A0C4D319xfw130b0d4vfe3M1I0e0i0$1l0!8/9xa60|0+9q108ZfJ9y0if02S0if8f-fu0H0+f,9K9D9x0S009r8U8!ae7O8$00d90+db0i3DaZ0o000v0Z2lf}fJf^f,f~g7g93Aae0z0R0O1MfT040a0i0)1i2Y0i0j0M2P0H0,202Pf%e?9pgu1Q1S3=1Y1!1$1(1*1,1.251?1^1`e{542E2v2x130A1+1-d+9!6S7Z6a6X3vdOcYdQ0U0U6{b{dX4Mg}6;dWbTg|6{fyd13Ah29@7Jd$72eB3Q7804b*7d0g7feVeJcwe5eh7reVb:3Lenhree7DaOhg4feM8VhCeQ13fab;eOb?g`ha3AdSc,5dg}cFc+h9h67:6g5XcDhThceoezd5hL5D9d8fcR8ch/8gcdeKdPhOc#hMdTh18Bb c}h68vhZ5/bPh_h%hrb00i8I8K9k8P8R8T9t8X9s8V8#8%8)8#8,1Z1y8:0,gth?hqasc@g{g}c`h{hR4piAc*8xiDh}93i3hWiFctg$bucO9h9j9phl7f9pg0ih9v8J9I0if{9M9F9H1 9J9Bf|9O9s9Q9S9l1$9W1 75ivc=a,8l8ng}9)c{h|4%j1iG95iM9.2piLh0j5jaiOd6i99}9 a1a31l0Ea69x8$aa9uadafahajalanhv5|hLh^h6aHj3iIjeaCh4h#0DaCjch5g}aHcLePi9b#jVaQaSaUaW0hbCa#0ia%a)i|cWcfi 8|g}a|jGj9a^jKi0j:jb61jdhOa|jSc4cObxb3b5b7b9bbj+g_iyhObrj=j}h6bnj^i5kgj{5.j9brk0h,c5k39{bzbBaZ0TbEeZjBh@hNh6bVkejP0DbRki7.g}bRjOjLbVkp83kr1maOjWb(hkb,0Ub.jA6bjCkCh2c2kFjL5Nj7j4hOk-h8kfk)i7jTkS0hc70ic93+kzk$kBkbh6csckk?cik.jHk:6;kNj_l8iOc;j,c?j.b^h27*k+lecAh kjlmkl6vkGcAjgaJkSh.cTh:lCh=hKl2lkiz65hQj9c.l9lMi2j|lwc/cub=jDh2iBc%lpc hVl7d3k=lw993Jd5hd13d(d*hG7ke3eK5~eUh+dBd`l{d;eil~2rekl@iw3=hzegdKdMm1dFdHmbe6d~mehH04l03*d#13er0jhGeTm0emd6eyd8g/mt7J0HeDeF0ChoeSeM2vmEmhmrhtmh7weYdN1Be%1O6Ge^6Q7X0.0:0=0,04.

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 :

\[\pi \approx 4 \times \frac{\text{nombre de points dans le disque}}{\text{nombre de points dans le carré}}\]

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.

Méthode de Monte-Carlo

On se donne donc :

  • une liste de nb_points aléatoires, tous dans le carré décrit ci-dessus. Cette liste est nommée points 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ées x et y 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.

###(Dés-)Active le code après la ligne # Tests (insensible à la casse)
(Ctrl+I)
Entrer ou sortir du mode "deux colonnes"
(Alt+: ; Ctrl pour inverser les colonnes)
Entrer ou sortir du mode "plein écran"
(Esc)
Tronquer ou non le feedback dans les terminaux (sortie standard & stacktrace / relancer le code pour appliquer)
Si activé, le texte copié dans le terminal est joint sur une seule ligne avant d'être copié dans le presse-papier

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.

Python
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