Aller au contenu

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 de element ou sans rapport avec ce dernier...,

  • element prend les diffĂ©rentes valeurs prĂ©sentes dans iterable,

  • iterable est un objet que Python peut parcourir. Ce peut ĂŞtre une liste, un tuple, un dictionnaire, un objet de type range...

Exemples

  • Les entiers entre 0 et 4 :

    >>> [x for x in range(5)]
    [0, 1, 2, 3, 4]
    
  • Les entiers pairs entre 0 et 8 :

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

  1. les entiers entre 0 et 10 (inclus l'un et l'autre)
  2. les entiers entre -10 et 10 (inclus l'un et l'autre)
  3. les entiers pairs entre -10 et 10 (inclus l'un et l'autre)
  4. les multiples de 3 entre -30 et 30 (inclus l'un et l'autre)
  5. vingt fois la valeur None
  6. la liste des caractères de "Hello World"
  7. la liste des caractères de "Hello World" en minuscule (Python considère que la minuscule de ' ' est ' ' !)

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
  1. [k for k in range(0, 11)]
  2. [k for k in range(-10, 11)]
  3. [k for k in range(-10, 11, 2)]
  4. [k for k in range(-30, 31, 3)]
  5. [None for _ in range(20)]. La variable d'itération n'étant pas utilisée, on peut la nommer _
  6. [caractere for caractere in "Hello World"]
  7. [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'utiliser ord("A")...

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

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 et iterable rĂ©pondent aux mĂŞme spĂ©cifications que dans la version de base,
  • condition est une expression renvoyant un boolĂ©en (True ou False).

Exemples

  • Les entiers pairs entre 0 et 10 :

    >>> [x for x in range(11) if x % 2 == 0]
    [0, 2, 4, 6, 8, 10]
    
  • Les notes comprises entre 12 et 14 (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 un tuple 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 de 4 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 de nombres
  • [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 de True que nombres compte de nombres pairs
  • [1 / x for x in nombres] renvoie la liste des inverses des valeurs de nombres
  • âś… [x for x in nombres if x != 11] renvoie bien une copie de nombres
  • âś… [x for x in nombres if x > 10] renvoie une liste vide car tous les Ă©lĂ©ments de nombres sont infĂ©rieurs ou Ă©gaux Ă  10
  • âś… [True for x in nombres if x % 2 == 0] renvoie une liste autant de fois True que nombres compte de nombres pairs
  • ❌ [1 / x for x in nombres] renvoie une erreur car on demande Ă  Python de diviser par 0
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é.

###(Dés-)Active le code après la ligne # Tests (insensible à la casse)
(Ctrl+I)
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 : 10/10

.128013rt=7*Cfl%b)1 2eĂ /vyg.:]8sw9nuph5aS(o3k_i46P;zĂ©[cdxm0050X0p0c0H0O0i0z0n0W0i0H0z0z0d010c0O0E010406050z0D0Z0Z0H0b0t040I0K0i0D0^0K0C050r0 1113150}0E04051l1e1o0r1l0}0X0O0s0-0/0;0?0F0O0u0F0i1C0F0c0{050(0k0i0p1x0:0=011B1D1F1D0c1L1N1J0c0b1m0c0F0-180z0E0H0C0?0o011P1z010h0*0p0C0H0Z0p1J1,1.1?1R1_1N1|1~0{0a0n0R0b0K0E0K0z0O1b0C0n0$1*0b0b0p0W2j1e210C1m0r1(2w1#1%1$1K0X230?1F0C1{2g1J1u1w0.1Q2G0O2I0C0K2M1J0E2p1m2u2w2!0~1-2k2O1@2T0b120i0{0n0m2t2(0|2%222*1R2,2.2:0o2?1.2^2u2F012}0H2/040n0L312v0}342{0?37390n0P3d332(353j2:0G3n3f3p3h360K2-382:0Q3u2_2)1y2|3z2~3a0e3E3g3H3i3J3B3a0y3N3w3P3y3A3k0B3V2`3X3r040m0!3$3G2P3Y3K0m2=1f2@3v3%3/3)0m303@323_3.2+3R390m3c3 3e3F3q440{0m3m483o3`433Z4d3t4g414b4k3*3D4n4a3x3|3M4t3O3{4c3*3U4y3W4A4q0m3#4E4i3I4q0o3,4K424M3K0o3?2!4o4v4B0o3~4W4u3(4Z474$4z4j4T4f4+4F4-3S0o4m4:4L3Q4N4s4_4R4{4T4x4~4p4T4D534Y4N4J574(4q0L4P5b4G3K0L4V3^4%5h3S0L4#2@1p2Y1e2M2z0X1%2E3x0W2U1 1m5v1n5t2$4g055B0$2Z4;1R0W0m0{030n1F0z0c0p0N0m1*0C0^1{0c5U0p0,0s380p0D0b0,5W0b0O2r0p1~5$0n2f2h0^0s5+2l1O2T0Z0k2p0z3-3q0{5V5X5Z3n0n5m1@0K0{0d6g6i1R0`040V3n6o3i0{0Y6n4,1R0M0{0h3z6y5O6v046x4g6h6z0?0K0A0{2R6F4`360{65675+6S4 016B040O0h6Z6b6I6*3x6k04020u0c0S6-3X0Z0O0{5f5r6M016q0x3u4X3X5Q5S5U0O5W5Y0o5#5%5|1N5,5.5:0,2R0h0U5@5/680n0K0D0n0U0u5.0,0q2;0!630n6W686a4v6c796e5q326L6G016/6m6K6u700{6s5J6 0C6w6^3/6$6D0b7#2+7!7S6 6O6Q1d7-7O7Z047E6Y7=6T6$6(7*2|7,2!7N6T6/020i6?7R827T6`4d6}327T71737T76045T6d5Y0L7d0O5(5*7h1N7j0n0O0Z1-0O7q2m7_694Q6+8n0N4*2@836!7Q7 0?6q7W2$7Y818L7T7%6E7{[email protected]%7;8(7?6V0K667F8!357}6)8?7H6,8`3X6/0j8P018c047L2v8M357Q898W6 935k8f6 8h4n743/8k8m7J5Y0P8q8s7g0n5-8v5;2l1v790O1M621-0b0n0e7C8E7G3(7I7a0N4/9b7O8O8}3/8R6t8U8|8-7|6C8Z9Y8#8V7M7T7/8+917@9I9S1@8^9-9(969*0{909:1R93529P846l9a9)9c6{048e2v8g0{729i8j5R8l789M0G9q7f629u7p0,2T2k2M9z9B0,9D0naj8D8:6X8F5g7+048I4^a08N6l919U7X8.9XaI8@9!7)9|6H8%aQ6.8*6RaU6U7^aA8=9$aR6%8_a*8{aWa49Q9`9193aHa;a1040da39^a54d9V7O9h4W9j1@9lah6e0Qak5)9san8w0X1cbd1O1#0_1N0n5+0c9J9kaf5T7l7n8r5:7r7t7v380n7z0m0G7Baz8;7`aD80aF9n0N4}aX8~aKa#aM8TaOa:a 7O8YaTa.9KaPa`8NaZ8,bR3{8/bJaCb.9;6Qa-b?9}a68Kb*980{0f9?b)bZa{8688a@a6bFa85N6Tb43^b65Pbtb95Y9G5B5$8ral8uao5}0)7q0%7DbB6062bIaBbraE8I9 b~6.bTb%9T7Vb26T8$91b#c2bY3a9*b,c29/cJb@a,cR918 c80{95cT7.a2c(a7c$8*1.0Xc#a#85870Sa~c+7O93cbaa04acb5ae778I0ybc8t9t7i9w8A7q7scw7wcy0,cAa)5l9Wd7c$cIb`8QcLaNcN9@c}9Z047(c@cY1R9+a!dD6HcXds6#b^dCdKc%a#93c*97cHa|c|dT6_a6cbdX3/9+9#dKcOc^0{c6c{c.d09gab8i6 b88I0Bd9bedcdkbi5*0-1B0h0h2p630,0D0C2i0U0,bp9FcCch770g1c0z0p0*0n0w2b1{ek0TbD0ne80n0Z2U0D0i0K0n0J0Y0n0j0n0veI0na}eHeI0l9Ha(bKdnaOd_dqa|aLdubWdwc3dy6!cQa#d*dH7PcVe)b:cBa#9=e.e#d#6ja?dQc9d!9_dVc.cFa9d;d2d?7Od^bO3+d{amd}1*8z5@ekec5$e57B0J2R0.0D0zeOcvbGeCfm19fpef0?b8cvbhale16(e41O0$e7e90cebbo5W3bePb;fxa$8I3+eVdWd18S6~bXcPaSdNcG8~e-e+9.eQb=f(7$dMe{6|eVd-fW9WcSe^dEd,c`f_c~a6bGc:0{c=f%c4aJ049{e+9de}c,e f=04b}f2b3d=4t0r5L0p2w2Xgq5u1v5w2z2C2x0H9B2w5v0}0r0$0(0*0z04.
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 :

\[\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)

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é.

###(Dés-)Active le code après la ligne # Tests (insensible à la casse)
(Ctrl+I)
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 : 10/10

.128013rAt=7*flb)1 2e/vyg:,-]8sw9nuph5aS(o3qk_i4+6P;Ă©[cdxm0050X0o0d0G0O0i0y0m0W0i0G0y0y0e010d0O0D010406050y0C0Z0Z0G0b0r040H0J0i0C0^0J0B050p0 1113150}0D04051l1e1o0p1l0}0X0O0q0-0/0;0?0E0O0s0E0i1C0E0d0{050(0j0i0o1x0:0=011B1D1F1D0d1L1N1J0d0b1m0d0E0-180y0D0G0B0?0n011P1z010h0*0o0B0G0Z0o1J1,1.1?1R1_1N1|1~0{0a0m0S0b0J0D0J0y0O1b0B0m0$1*0b0b0o0W2j1e210B1m0p1(2w1#1%1$1K0X230?1F0B1{2g1J1u1w0.1Q2G0O2I0B0J2M1J0D2p1m2u2w2!0~1-2k2O1@2T0b120i0{0m0l2t2(0|2%222*1R2,2.2:0n2?1.2^2u2F012}0G2/040m0K312v0}342{0?37390m0P3d332(353j2:0F3n3f3p3h360J2-382:0R3u2_2)1y2|3z2~3a0f3E3g3H3i3J3B3a0x3N3w3P3y3A3k0A3V2`3X3r040l0!3$3G2P3Y3K0l2=1f2@3v3%3/3)0l303@323_3.2+3R390l3c3 3e3F3q440{0l3m483o3`433Z4d3t4g1p2Y1e2M2z0X1%2E3x0W2U1 1m4r1n4p2$4n4x0$2Z3W3/0M0B0{0h2d0Z3n0m4a3x0B4M04121(4R4T3X4L0{0O0Z2f0b0d4!3O3{0{0y0L4,3-354%044O0J4Q4g4S4/2+4W0b1.0X4}4.4J1@4`4)4+4-4 4#4:04540B564~2!065o5g5a0{0$0h584i2|0h5s0O0y0(0B0W0o0N3z1C2R0o3n5q1R0`040I5L512|0{0Y5R595N0{0u5v425T040r5W5w0?5O0k0t3u0m5;505X0?0M0{2p0d0C0b1d5f5S3i4;4?5e2$61015O5Q4n674W5V605@010J0{0g5#3q5U6l3x6i040Q6o3(0{5)6f5+6h6j6t5h6w666g5-3u5p6c0{0B0j0N2f2R0d0y6B1@6q0e6S1R0Z0O4d0!0!0N6#3,4g416m046O0B6Q6W0?6U6;680{0V6a6E6y6Y0{3~2!5?6y6q6k6x5$625i55576b6F0{0I0k6@6q0v6@6~3*5*776^045!76357l702@727o746@537a5m2@5M5,7e7g7s6p0{7j7J3X7l3?6|7o6G7N4K4N3z7A0{0N7h0z4(5 717F360j5`1.0s5K7c6y697n6,6L6N0J6P6R7;7S0{0k0w6H7*4W0X1.0y0N5E0b0.7:7)676?7U1@5O0V7@4U0{0D6@5_4{7X8h5%8o8t6=7$042R7Y6-7{6/7}8e6g8q0O5u8w365z5B1.5E5G0b5I2I8l3X7?7~6,8v7R358j8V3/7l6)8#3x5O0w7r8G6y4W8!7E678%8Y3x7P8(8i0{0w7I8;7y0{020i0d0T6V8L8}8{8W9083670W0l0{030m0c0h1_0W0E1O0C2I0m0q380o5}0m0G0D2X0J9q0U1O2m0D0O4^4U7,6-8S6/8~5Y5P9R0?7l4f93357z8L6L0{269U7p6{8^6g8587890o8b1N9)7T9Y7K040p8B7_6.6:9d3/9^3^1e4G0o2w2Xa74q1v4s2z2C2x0G1Maa0p4r0}ak0%0)0+04.