Chapitre 3 : Algorithmes sur les listes.

Introduction :

On vous donne une longue liste : l'âge de tous les habitants d'un village, ou un mélange d'objets en tout genre.

Comment savoir combien ont plus de 18 ans, ou retrouver le plus jeune et le plus âgé, sans tout examiner à la main ?

1. La boucle for

En Python, la boucle for permet d’itérer sur un conteneur (liste, chaîne de caractères, dictionnaire, ensemble...). À chaque tour de boucle, la variable prend la valeur du prochain élément du conteneur, ce qui permet de traiter facilement chaque élément un par un.

fruits = ["pomme", "banane", "cerise"]

for fruit in fruits:
    print(fruit)

Ici, la variable fruit vaudra successivement "pomme", "banane", puis "cerise". C’est l’outil le plus pratique pour examiner chaque élément d’une collection.

2. Exercice : identification du conteneur parcouru par une boucle for.

À faire dans le cahier.

On considère la boucle suivante :

liste = [9, 6, 4, 0]
for machin in liste:
    print(machin)
  1. Quel est le conteneur parcouru par cette boucle ?
  2. Quelles seront successivement les valeurs de la variable machin au cours de l’exécution ?

3. Exercice : boucle for avec range et indices.

À faire dans le cahier.

On considère la boucle suivante :

liste = [9, 6, 4, 0]
for machin in range(len(liste)):
    print(liste[machin])
  1. Quel est le conteneur parcouru par cette boucle ?
  2. Quelles seront successivement les valeurs de la variable machin ?
  3. Quels seront les éléments effectivement affichés par le programme ?

4. Itération sur les éléments ou sur les indices

En Python, il existe deux façons classiques de parcourir une liste :

Exemple :

fruits = ["pomme", "banane", "cerise"]

# Accès direct aux éléments
for e in fruits:
    print(e)

# Accès par les indices
for i in range(len(fruits)):
    print(i, fruits[i])

5. Exercice : affichage des éléments d'une liste.

Créer une fonction affiche_liste qui prend une liste de nombres en paramètre et qui les affiche un par un.

nombres = [4, 7, 2, 9, 5, 12, 45, 78, 3, 15, 22, 37, 88, 101, 6, 19, 33, 41, 56, 72, 81, 90, 102, 111, 134, 145, 156, 167, 178, 189, 200, 215, 230, 245, 260, 275, 290, 305, 320, 335] def affiche_liste(liste): # parcourir la liste et afficher chaque élément ... affiche_liste(nombres) # exécute la fonction avec la liste nombres

    
>>>

6. Problème : combien de jours la température a-t-elle grimpé ?

Une station météo relève la température maximale de chaque jour et range ces valeurs dans une liste, dans l’ordre des jours : la première valeur est celle du premier jour, la deuxième celle du lendemain, et ainsi de suite.

Un climatologue veut compter le nombre de fois où il a fait plus chaud le lendemain.

Ici, regarder un élément tout seul ne sert à rien : pour savoir si la température a monté, il faut comparer un élément avec le suivant. Or un for temperature in liste ne te donne pas accès à la valeur d’après : il faut donc parcourir les indices et comparer liste[i] à liste[i+1].

Attention : le tout dernier jour n’a pas de lendemain !!!

Compléter la fonction jours_de_hausse qui prend une liste de températures et renvoie le nombre de fois où la température du lendemain est strictement supérieure à celle du jour même.

Exemple :

>>> jours_de_hausse([12, 15, 14, 14, 18, 20])
3

La température monte du jour 0 au jour 1 (12 → 15), du jour 3 au jour 4 (14 → 18) et du jour 4 au jour 5 (18 → 20) : cela fait 3 hausses.

def jours_de_hausse(temperatures): compteur = 0 for i in range(.......................) : if temperatures[i+1] > ....................... : ................. return ............... temperatures = [12, 15, 14, 14, 18, 20, 19, 21, 25, 24, 26, 26, 23, 27, 30] print(f"La température a grimpé pendant {jours_de_hausse(temperatures)} jours.")

    
>>>

7. Exercice : somme des éléments d'une liste.

Compléter la fonction somme ci-dessous qui prend une liste de nombres en paramètre et retourne la somme de ces nombres.

Si la liste est vide, elle renverra le string "Erreur, liste vide".

Exemples :

>>> somme([1,2,3,4,5,6])
21
>>> somme([5])
5
>>> somme([])
"Erreur, liste vide"
def somme(liste): if .......... return "Erreur, liste vide" sortie = ...... for element in ....... : sortie = sortie + .... return ...... liste = [2, 5, 8, 9, 12] print(f"La somme de la liste {liste} est {somme(liste)}.")

    
>>>

8. Exercice : moyenne des éléments d'une liste.

Créer une fonction moyenne_liste qui prend une liste de nombres en paramètre et qui retourne leur moyenne. Si la liste est vide, la fonction devra renvoyer le string "Erreur, liste vide".

def moyenne_liste(liste): # calculer la moyenne des nombres de la liste ... liste = [2, 5, 8, 9, 12] print(f"La moyenne de la liste {liste} est {moyenne_liste(liste)}.")

    
>>>

9. Exercice : incrémentation des éléments d'une liste.

Compléter une fonction Python nommée incrementer_elements qui prend une liste de nombres en entrée et renvoie une nouvelle liste contenant chaque élément augmenté de 1.

def incrementer_elements(liste): nouvelle_liste = [] for .................. : ..................... return ............... liste_initiale = [12, 8, 7, 2] print(f"Si on ajoute 1 à chaque nombre de {liste_initiale}, on obtient {incrementer_elements(liste_initiale)}.")

    
>>>

10. Exercice : comptage d'éléments sous un seuil.

Un magasin enregistre le prix de ses articles. Écrire une fonction articles_pas_chers qui prend une liste de prix (nombres positifs) et retourne le nombre d’articles coûtant 10 euros ou moins.

Exemple :

>>> articles_pas_chers([5, 12, 8, 20, 3, 15, 7])
4
def articles_pas_chers(prix_articles): compteur = 0 for prix in prix_articles: if ............... : ................. return ............... prix_articles = [5, 12, 8, 20, 3, 15, 7, 9, 11, 14, 6, 2, 30, 4, 17, 19, 23, 5, 7, 8, 12, 6, 9, 10, 25, 3, 4, 18, 22, 13, 7, 5, 6, 8] print(f"Il y a {articles_pas_chers(prix_articles)} articles coutant 10 euros ou moins.")

    
>>>

11. Exercice : comptage des notes admises.

Un professeur a relevé les notes de ses élèves. Écrire une fonction admis qui prend en paramètre une liste de notes (valeurs entières entre 0 et 20) et retourne le nombre d’élèves ayant obtenu au moins 10.

Exemple :

>>> admis([12, 8, 14, 9, 10, 7, 18])
4
def admis(liste_notes): compteur = 0 for note in liste_notes: if ............... : ................. return ............... notes = [12, 8, 14, 9, 10, 7, 18, 4, 19, 3, 11, 15, 6, 13, 10, 2, 20, 7, 5, 17, 16, 8, 12, 14, 9, 11, 19, 6, 10, 13, 18, 7, 4, 15] print(f"{admis(notes)} élèves ont été admis.")

    
>>>

12. Exercice : conversion d'une chaîne en liste de caractères.

Créer une fonction caracteres qui prend une chaîne de caractères texte en paramètre et qui renvoie une liste contenant tous les caractères de cette chaîne.

def caracteres(texte): # transformer le string en liste de caractères ... texte = "coucou" print(f"Les caractères de '{texte}' sont {caracteres(texte)}.")

    
>>>

13. Exercice : caractères uniques d'une chaîne.

Créer une fonction caracteres_uniques qui prend une chaîne de caractères texte en paramètre et qui renvoie une liste contenant les caractères de cette chaîne, chaque caractère n’apparaissant qu’une seule fois.

def caracteres_uniques(texte): resultat = [] for caractere in texte: if .............: resultat.append(.............) return ............. texte = "coucou" print(f"Les caractères uniques de '{texte}' sont {caracteres_uniques(texte)}.")

    
>>>

14. Problème : combien de matchs l'équipe a-t-elle gagnés ?

Le secrétaire d’un club de football note les résultats de la saison dans deux listes séparées : les buts marqués par l’équipe, et les buts encaissés. Les deux listes sont rangées dans le même ordre : la première valeur de chaque liste concerne le premier match, la deuxième valeur le deuxième match, etc.

L’équipe gagne un match quand elle marque strictement plus de buts qu’elle n’en encaisse.

Le problème : pour juger un match, il faut lire deux listes en même temps. Un for buts in marques ne te dit pas à quel match tu en es, donc tu ne peux pas retrouver les buts encaissés correspondants. La solution est de parcourir les indices avec range(len(marques)), puis de comparer marques[i] et encaisses[i] : ces deux valeurs concernent le même match.

Écris la fonction matchs_gagnes qui prend les deux listes en paramètres (elles ont la même longueur) et qui renvoie le nombre de matchs gagnés.

Exemple :

>>> matchs_gagnes([2, 0, 3, 1, 4], [1, 0, 5, 2, 0])
2

Seuls le premier match (2 buts contre 1) et le dernier (4 buts contre 0) sont gagnés.

def matchs_gagnes(marques, encaisses): # À toi d'écrire le code de la fonction. ... marques = [2, 0, 3, 1, 4, 2, 1, 0, 5, 3] encaisses = [1, 0, 5, 2, 0, 2, 3, 1, 2, 3] print(f"L'équipe a gagné {matchs_gagnes(marques, encaisses)} matchs.")

    
>>>

15. Problème : quelles places sont encore libres ?

La caisse d’un cinéma garde en mémoire l’état d’une rangée de fauteuils dans une liste : chaque case contient "libre" ou "occupée". Les fauteuils sont numérotés à partir de 0, si bien que le fauteuil numéro i est décrit par la case d’indice i.

Un spectateur arrive et demande la liste des numéros des fauteuils encore disponibles.

Cette fois, ce n’est pas le contenu des cases qui nous intéresse : savoir qu’une place libre contient "libre" ne nous apprend rien. Ce qu’il faut renvoyer, c’est l’endroit où elle se trouve. Or un for place in rangee te donne le mot "libre" mais oublie sa position : il faut donc parcourir les indices avec range(len(rangee)), tester rangee[i], et ajouter i à la liste résultat.

Compléter la fonction places_libres qui prend la liste des états d’une rangée et renvoie la liste des numéros des fauteuils libres, dans l’ordre croissant.

Exemple :

>>> places_libres(["occupée", "libre", "occupée", "occupée", "libre"])
[1, 4]

Les fauteuils libres sont bien ceux des indices 1 et 4.

def places_libres(rangee): ... rangee = ["occupée", "libre", "occupée", "occupée", "libre", "libre", "occupée", "occupée", "libre", "occupée", "libre", "libre", "occupée", "libre"] print(f"Les places libres sont les numéros {places_libres(rangee)}.")

    
>>>

16. Exercice : découpage d'une chaîne en mots.

Compléter la fonction trouve_les_mots qui prend une chaîne de caractères texte et qui renvoie une liste contenant les mots (séparés par des espaces).

Exemple :

>>> trouve_les_mots("bonjour le monde")
['bonjour', 'le', 'monde']
def trouve_les_mots(texte): if texte == "": # si le texte est vide, on retourne une liste vide return [] liste = [] mot_a_completer = "" for carac in texte: if carac == " ": # si le caractère est un espace if mot_a_completer != "": # si mot_a_completer est non vide ..................... # ajouter le mot terminé à la liste ..................... # réinitialisation de mot_a_completer else: # le caractère doit être ajouté au mot_a_completer ........................... # ajouter le caractère à mot_a_completer if ..................: # cas où texte ne finit pas par un espace ..................... # ajouter le dernier mot à la liste return liste texte = "bonjour les élèves de première NSI" print(f"Les mots du texte sont {trouve_les_mots(texte)}."

    
>>>

17. Les listes par compréhension

En Python, il existe une manière rapide et élégante de créer des listes : la compréhension de liste.

Elle permet de générer une nouvelle liste à partir d’une autre, en appliquant une règle et éventuellement une condition.

nouvelle_liste = [règle for variable in liste_existante if condition]

Par exemple, pour obtenir les carrés des nombres pairs entre 0 et 9 :

nombres = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
carres_pairs = [n**2 for n in nombres if n % 2 == 0]
print(carres_pairs)   # Résultat : [0, 4, 16, 36, 64]

18. Exercice : liste par compréhension des doubles.

Compléter l’expression ci-dessous pour créer une liste doubles contenant les doubles des nombres de 1 à 10 en utilisant une liste par compréhension.

Exemple attendu :

[2, 4, 6, 8, 10, 12, 14, 16, 18, 20]
doubles = [ .... for i in .... ] print(f"Les doubles sont {doubles}.")

    
>>>

19. Exercice : liste par compréhension avec réduction de prix.

Un magasin vend 10 articles dont les prix sont les entiers de 1 à 10 euros. Compléter le code ci-dessous pour créer une liste prix_reduits qui contient les prix après une réduction de 20 % (multiplier chaque prix par 0.8), en utilisant une liste par compréhension.

Exemple attendu (arrondi à 1 décimale) :

[0.8, 1.6, 2.4, 3.2, 4.0, 4.8, 5.6, 6.4, 7.2, 8.0]
prix = [1,2,3,4,5,6,7,8,9,10] prix_reduits = [ round(... , 1) for i in .... ] print(f"Les prix réduits sont {prix_reduits}.")

    
>>>

20. Exercice : liste par compréhension avec condition.

Une liste par compréhension peut aussi filtrer les éléments grâce à un if placé à la fin.

Compléter le code ci-dessous pour créer une liste pairs contenant uniquement les nombres pairs de 1 à 20, en utilisant une liste par compréhension avec condition.

Exemple attendu :

[2, 4, 6, 8, 10, 12, 14, 16, 18, 20]
pairs = [ .... for i in .... if .... ] print(f"Les nombres pairs sont {pairs}.")

    
>>>

21. Exercice : liste par compréhension sur des chaînes.

On dispose d’une liste de prénoms. On souhaite obtenir la liste de leurs initiales (première lettre, en majuscule).

Compléter le code ci-dessous pour créer la liste initiales à l’aide d’une liste par compréhension. On pourra utiliser prenom[0] pour obtenir la première lettre et .upper() pour la mettre en majuscule.

Exemple attendu :

['A', 'B', 'C', 'Z', 'M']
prenoms = ["alice", "bob", "chloe", "zoe", "malik"] initiales = [ .... for prenom in .... ] print(f"Les initiales sont {initiales}.")

    
>>>

22. Défi : générer un bulletin en une ligne.

Le secrétariat dispose de deux listes séparées : les prénoms des élèves, et leurs moyennes rangées dans le même ordre (le premier prénom correspond à la première moyenne, etc.).

On voudrait fabriquer, en une seule ligne, un bulletin : une liste de phrases où chaque élève est déclaré "admis" si sa moyenne est supérieure ou égale à 10, et "recalé" sinon.

Comme il y a deux listes à lire en même temps, on ne peut pas se contenter de parcourir directement les éléments : on va parcourir les indices avec range(len(prenoms)), puis lire prenoms[i] et moyennes[i].

Pour choisir le texte à produire selon la moyenne, on place devant le for une expression conditionnelle de la forme valeur_si_vrai if condition else valeur_si_faux. La compréhension a donc cette structure :

bulletin = [ (  ...  if  ...  else  ...  )  for i in range(len(prenoms)) ]
#              └────── ce qu'on met dans la liste ──────┘   └── parcours ──┘

Compléter la ligne ci-dessous pour construire la liste bulletin.

Exemple attendu :

['Alice : admis', 'Bob : recalé', 'Chloé : admis', 'David : recalé', 'Emma : admis']
prenoms = ["Alice", "Bob", "Chloé", "David", "Emma"] moyennes = [14, 8, 11, 6, 17] bulletin = [ .... for i in range(len(prenoms)) ] for ligne in bulletin: print(ligne)

    
>>>

23. Recherche du minimum dans une liste

La recherche du minimum dans une liste consiste à identifier l'élément ayant la plus petite valeur.

Retenir dans les grandes lignes que :

  1. On initialise en partant du principe que le candidat pour être le minimum est temporairement le premier élément.
  2. Pour chaque autre élément :
    • Si on trouve un élément inférieur à celui actuel, on change de candidat pour être le minimum.

Observe l'algorithme en action : le candidat minimum (en orange) ne change que lorsqu'on rencontre un élément plus petit que lui.

élément de la liste candidat minimum élément comparé minimum trouvé

Clique sur « Démarrer / Redémarrer » pour lancer l'animation.

24. Exercice : recherche du minimum d'une liste.

Compléter la fonction minimum_liste qui prend une liste de nombres (au moins un élément) et qui retourne le plus petit élément.

def minimum_liste(liste): mini = ......... # à l'initialisation, le plus petit est le premier élément for element in ........ : if ......... : mini = ...... return mini import random l = [random.randint(1,1000) for _ in range(20)] print(f"Le minimum de {l} est {minimum_liste(l)}.")

    
>>>

25. Exercice : recherche du maximum d'une liste.

Écrire la fonction maximum_liste qui prend une liste de nombres (au moins un élément) et qui retourne le plus grand élément.

def maximum_liste(liste): ................. # à l'initialisation, le plus grand est le premier élément for ......................... : if .................. : .................. return ....................... import random l = [random.randint(1,1000) for _ in range(20)] print(f"Le maximum de {l} est {maximum_liste(l)}.")

    
>>>

26. Exercice : erreur d'initialisation dans un calcul de maximum.

À faire dans le cahier.

Voici une fonction mauvais_maximum_liste qui prétend calculer le maximum d’une liste de nombres. Elle initialise le maximum à 0.

Commence par exécuter la fonction avec la liste donnée et observe le résultat : cela a l’air correct. Puis modifie la liste afin de montrer que cette fonction est en réalité fausse.

Quand tu as trouvé, explique dans ton cahier le problème.

liste = [4, -2, 7, -5, 3] def mauvais_maximum_liste(liste): maxi = 0 # Mauvaise initialisation for element in liste: if element > maxi: maxi = element return maxi print(f"Le maximum de cette liste est {mauvais_maximum_liste(liste)}.")

    
>>>

27. Problème : à quelle heure a-t-il fait le plus chaud ?

Une station météo relève la température (en degrés) toutes les heures, de minuit (heure 0) jusqu’à 23 heures. Toutes ces mesures sont rangées, dans l’ordre, dans une liste : la première valeur correspond à l’heure 0, la deuxième à l’heure 1, et ainsi de suite.

Un journaliste ne veut pas connaître la température la plus élevée de la journée, mais souhaite savoir à quelle heure ce maximum a été atteint. Autrement dit, ce n’est pas la valeur du maximum qui l’intéresse, mais sa position (son indice) dans la liste.

Écris une fonction indice_du_maximum qui prend en paramètre une liste de nombres (supposée non vide) et qui renvoie l’indice de son plus grand élément. Si le maximum apparaît plusieurs fois, la fonction renverra l’indice de sa première apparition. Tu ne dois utiliser ni la fonction max ni la méthode .index() : le but est de parcourir toi-même la liste.

Exemple :

>>> temperatures = [14, 16, 19, 23, 25, 24, 21, 18]
>>> indice_du_maximum(temperatures)
4

Ici la température maximale (25 degrés) a été relevée à l’indice 4, c’est-à-dire à 4 heures du matin.

def indice_du_maximum(liste): # À toi d'écrire le code de la fonction. ... temperatures = [14, 16, 19, 23, 25, 24, 21, 18] print(f"Le maximum a été atteint à l'indice {indice_du_maximum(temperatures)}.")

    
>>>