Aller au contenu

Parcourir un itérable

Itérables et parcours par valeur

Les codes suivants sont équivalents : ils affichent tous successivement les nombres 0, 1, $\ldots$, 5.

🐍 Code Python
1
2
for i in range(5):
    print(i)
🐍 Code Python
1
2
for i in 0, 1, 2, 3, 4:
    print(i)
🐍 Code Python
1
2
for i in [0, 1, 2, 3, 4]:
    print(i)
🐍 Code Python
1
2
for i in (0, 1, 2, 3, 4):
    print(i)

On dit que range(5), la liste [0, 1, 2, 3, 4], et le tuple (0, 1, 2, 3, 4) sont des itérables. On appelle i la variable de boucle (on peut lui donner un autre nom si on le souhaite). On exécute alors le corps de la boucle autant de fois qu'il y a d'élément présent dans l'itérable, la variable de boucle prenant successivement chacune des valeurs de l'itérable.

Les chaînes de caractères sont également des itérables. Les éléments qui le constituent sont alors chacun des caractères de la chaîne de caractères. Par exemple, les deux codes ci-dessous sont équivalents (on utilise c comme nom pour la variable de boucle car les valeurs successives de celle-ci sont les c​aractères du mot "bonjour") :

🐍 Code Python
1
2
for c in "bonjour":
    print(c)

:space 1em

🐍 Code Python
1
2
for c in "b", "o", "n", "j", "o", "u", "r":
    print(c)

Attention toutefois à ce sur quoi on itère !

🐍 Code Python
1
2
for m in "bonjour", "tout", "le", "monde !":
    print(m)

Dans cet exemple, l'itérable est constitué de quatre éléments, la variable de boucle m (pour m​ot) prend successivement les valeurs "bonjour"​, "tout"​, "le"​, et enfin "monde !".

Compter le nombre d'éléments d'un itérable

La longueur d'un itérable iter est définie comme le nombre d'éléments qui le composent.

Par exemple :

  • [7, 8, 9] est constitué de 3 éléments : 7, 8 et 9 ;
  • "bonjour" est constitué de 7 éléments : "b"​, "o"​, $\ldots$, "r" ;
  • ["salut"] est constitué d'un unique élément "salut".

Écrire une fonction longueur qui prend en argument un iterable et qui en renvoie la longueur.

🐍 Code Python
1
2
3
4
5
6
7
def longueur(iterable):
    """ Iterable -> int
    Compte le nombre d'éléments dont est constitué iter """
    n = 0
    for e in iterable:
        ...
    return ...

Déterminer si un élément fait partie d'un itérable

Écrire une fonction appartient qui prend en argument un iterable et un élément recherché elem renvoie True si elem est un des éléments de l'itérable et False sinon.

Par exemple :

  • appartient([7, 8, 9], 9) renvoie True car 9 est le troisième élément de l'itérable [7, 8, 9] ;
  • appartient([7, 8, 9], 5) renvoie False car 5 n'est pas un des éléments de l'itérable ;
  • appartient("bonjour", "b") renvoie True car "b" est le premier élément de l'itérable "bonjour" ;
  • appartient(["salut", "toi"], "t") renvoie False car "t" n'est pas un des éléments de l'itérable.
🐍 Code Python
1
2
3
4
def appartient(iterable, elem):
    """ Iterable, Element -> bool
    Renvoie True si elem est l'un des éléments de iterable, False sinon """
    pass

Que renvoie appartient(["bonjour"], "b") ? Justifier votre réponse.

Compter le nombre d'occurences d'un élément

Lorsqu'un élément apparaît dans un itérable, on parle d'une occurrence de cet élément dans l'itérable. Si celui-ci apparaît plusieurs fois, alors on dit qu'il y a plusieurs occurrences de cet élément dans l'itérable.

Par exemple, comme "n" apparaît 2 fois dans "montagne"​, on dit que n possède deux occurences dans "bonjour"​. De même 1 possède 4 occurences dans [0, 1, 0, 0, 1, 1, 1], mais aucune dans [4, 5, 6].

Écrire une fonction nombre_occurrences qui prend en arguments un itérable iterable et un éléments elem et qui renvoie le nombre d'occurrences de elem dans iterable.

🐍 Code Python
1
2
3
4
def nombre_occurrences(iterable, elem):
    """ Iterable, Element -> int
    Renvoie le nombre de fois qu'apparaît elem dans iterable """
    pass

Écrire les tests correspondant aux exemples donnés dans l'énoncé. Vérifier que votre fonction passe les tests.

Plus long mot d'une liste

Dans cette question, on cherche à déterminer le plus long mot d'une liste de mots définie à l'avance. Par exemple, le plus long mot de la liste ["Mon", "voisin", "très", "malin"] est "voisin", constitué de 6 lettres.

On utilise pour cela l'algorithme suivant :

  • Initialement, le plus long mot de la liste a une longueur record de 0 (on n'a étudié aucun mot dans la liste). Puis, on parcourt tous les mots de la liste liste_mots.

  • Pour chaque mot m de liste_mots, on calcule le nombre de lettres n du mot m (à l'aide de la fonction longueur). On compare n au record du plus long mot découvert jusqu'à présent :

    • si n est supérieur à record, alors c'est que le mot m est le plus long parmi les mots parcourus, il faut donc mettre à jour record.
    • sinon, le record du mot le plus long reste inchangé.
  • Lorsque tous les éléments ont été parcourus, on renvoie la valeur de record.

Compléter les ... du code de la fonction plus_long_mot et tester votre fonction.

Vous pouvez éventuellement insérer une ou des lignes de code supplémentaires par rapport au code donné dans l'énoncé si vous le souhaitez, bien que cela ne soit pas obligatoire.

🐍 Code Python
1
2
3
4
5
6
7
8
9
def plus_long_mot(liste_mots):
    """ [str] -> int
    Renvoie le nombre de lettres du plus long mot de la liste """
    record = ...
    for ...:
        n = ...
        if ...:
            ...
    return ...
  1. Justifier les assertions ci-dessus.

  2. Adapter le code de la fonction plus_long_mot en une fonction mot_plus_long qui prend en entrée une liste liste_mots et qui renvoie le mot le plus long de la liste. Par exemple, mot_plus_long(["bonjour", "tout", "le", "monde"]) devra renvoyer "bonjour".

    🐍 Code Python
    1
    2
    3
    4
    5
    6
    7
    8
    def plus_long_mot(liste_mots):
        """ [str] -> str
        Renvoie le plus long mot de liste_mots """
        record = 0
        mot_plus_long = ""
        for ...:
            # À compléter (une ou plusieurs lignes)
        return ... 
    

Parcours par indice d'un itérable

Parfois, parcourir les valeurs des éléments d'un itérable les unes après les autres ne suffit pas.

Pour comprendre cela, considérons le problème suivant. Une station métérologique relève la température extérieure chaque jour. À la fin du mois, elle calcule la température moyenne sur le mois. Les données sont stockées dans une liste temperatures.

🐍 Code Python
1
2
3
4
mois = ["Janvier", "Février", "Mars", "Avril", "Mai", "Juin",
        "Juillet", "Août", "Septembre", "Octobre", "Novembre", "Décembre"]
temperatures = [24.8, 25.8, 25.7, 25.2, 24.9, 23.9,
                23.3, 23.2, 23.7, 24.1, 24.5, 24.4]
  1. D'après les données présentes dans le relevé temperatures :
    1. Quel est le premier mois pendant lequel la température moyenne est inférieure à $24^{\circ}C$ en moyenne ?
    2. Quel est le mois le plus chaud en moyenne ? Le mois le plus froid en moyenne ?
  2. Expliquer pourquoi on ne peut pas écrire une fonction python qui réponde aux questions précédentes en parcourant par valeur la liste temperatures.

Dans une liste, chaque élément est repéré de manière unique à l'aide de son indice, en commençant à partir de $0$.

Par exemple, on définit liste de la manière suivante :

🐍 Code Python
1
2
liste     = ["b", "o", "n", "j", "o", "u", "r"] 
# indices     0    1    2    3    4    5    6

On a alors :

  • l'élément d'indice 0 est "b"​, c'est le premier élément de liste. On le note liste[0].
  • l'élément d'indice 6 est "r"​, c'est le dernier élément de liste. On le note liste[6].
  • les deux occurrences de "o" ont pour indice 1 et 4. Ce sont les deuxièmes et cinquièmes éléments de liste. On les note liste[1] et liste[4]
🐍 Code Python
1
2
3
print(liste[0])    
print(liste[6])    
print(liste[1], liste[4])    
⚙️ Résultat
b
r
o o
  1. Donner mois[1], mois[4], temperatures[6], temperatures[7].

  2. Donner mois[longueur(mois) - 2]

  3. lst est une liste de n éléments, et i est un indice d'un élément de cette liste.

    1. Donner un encadrement de i.

    2. Quel est le lien entre lst[i] et lst[i + 1] ? Entre lst[i - 1] et lst[i] ?

    3. À quoi correspond lst[n - 1] ?

On considère le code de la fonction premier_mois_sous ci-dessous. Cette fonction permet de répondre au problème de l'énoncé en renvoyant l'indice du premier mois pendant lequel la température moyenne est inférieure à $24^{\circ}C$.

🐍 Code Python
1
2
3
4
5
6
7
8
9
def premier_mois_sous24(temperatures):
    """ [float] -> int
    Renvoie l'indice du premier mois dont la température mensuelle moyenne est inférieure à 24C.
    Renvoie -1 si aucun mois ne possède une température mensuelle moyenne inférieure à 24C. """
    for i in range(len(temperatures)):
        t = temperatures[i]
        if ...:
            return ...
    return ...
    1. Compléter et tester le code.

    2. Adapter le code de premier_mois_sous24 en une fonction premier_mois_sous qui prend en arguments une liste de temperatures et une température seuil et qui renvoie le nom du premier mois pendant lequel la température mensuelle moyenne est inférieure à seuil.

      Votre fonction renverra "" si aucune température n'est inférieure à seuil. Vous utiliserez la liste mois pour déterminer le nom du mois à partir de son indice.

      🐍 Code Python
      1
      2
      3
      4
      5
      def premier_mois_sous(temperatures, seuil):
          """ [float] -> str
          Renvoie le premier mois pendant lequel la température mensuelle moyenne est inférieure à seuil
          Renvoie "" si aucun mois ne possède une température mensuelle moyenne inférieure à seuil """
          pass
      
  1. Challenge. Écrire une fonction mois_plus_chaud qui prend en argument une liste temperatures et qui renvoie le nom du mois le plus chaud correspondant.

Prix total d'un panier

Un supermarché souhaite écrire un code python pour faire fonctionner sa caisse automatique. Lorsqu'un client passe en caisse, il scanne son panier et trois listes sont automatiquement créées :

  • une liste objets qui contient le nom des objets scannés par le client ;
  • une liste quantite qui contient la quantité de chaque objet ;
  • une liste prix qui contient le prix à l'unité de chaque objet.

Par exemple, on peut avoir :

🐍 Code Python
1
2
3
objets = ["pomme", "ananas", "prune"]
quantite = [3, 1, 6]
prix = [100, 500, 50]

:space 1em

Dans cette situation, le client souhaite acheter 3 pommes à 100 francs, 1 ananas à 500 francs, et 6 prunes à 50 francs. Il doit donc payer un total de 1100 francs.

Compléter les ... présents dans le code de la fonction prix_total ci-dessous.

🐍 Code Python
1
2
3
4
5
6
7
def prix_total(quantites, prix):
    """ [int], [int] -> int
    Renvoie le prix total d'un panier """
    p = 0
    for i in range(...):
        p = p + ...
    return ...

Deux éléments consécutifs identiques

Écrire une fonction deux_suivants_egaux qui prend en argument une liste lst et qui renvoie True s'il existe deux éléments consécutifs identiques, False sinon.

On rappelle que si i est l'indice d'un élément de lst, alors i + 1 est l'indice de l'élément suivant dans lst.

🐍 Code Python
1
2
3
4
def deux_suivants_egaux(lst):
    """ [int] -> bool
    Renvoie True si on peut trouver deux éléments consécutifs égaux dans la liste, False sinon """
    pass

Adapter le code de la fonction deux_suivants_egaux en une fonction est_trie_croissant qui prend en argument une liste d'entiers lst et qui renvoie True si celle-ci est triée par ordre croissant, False sinon.

Par exemple :

⚙️ Résultat
>>> est_trie_croissant([1, 2, 3])
True
>>> est_trie_croissant([1, 3, 2, 4, 5, 6])
False

Pour cela, on pourra parcourir les éléments de la liste les uns après les autres: si on trouve deux éléments a et b consécutifs (a apparaissant en premier premier dans la liste, b suivant a) tels que a est plus grand que b, alors on est certain que la liste n'est pas triée par ordre croissant, et on peut renvoyer False immédiatement.

Si on a parcouru toute la liste sans rencontrer de "problème", c'est que la liste est triée par ordre croissant et on peut renvoyer True.