12. Itérer sur une séquence#

Nous avons présentés précédement les n-uplets, les chaines et les ranges. Nous allons maintenant voir comment manipuler les éléments contenus à l’interieur. Pour cela, nous devons introduire la boucle “pour chaque”. La boucle for

La boucle “pour chaque” permet d’exécuter un ensemble d’instructions pour chaque élément contenu dans une séquence. L’exemple suivant nous montre comment afficher les voyelles contenue dans une chaine.

chaine = input()
for c in chaine :
    if c in "aeiouyAEIOUY" :
        print( c )

La boucle est composée d’une déclaration for c in chaine : et d’un bloc de code. Son fonctionnement est le suivant. Chaque caractère de la sequence chaine est associé successivement dans la variable c. Pour chaque valeur, les instructions du bloc de code sont exécutées.

De manière générale, voici la syntaxe d’une boucle for.

for variable in sequence :
    instructions
    ...
    ...

Les boucles for peuvent être utilisées avec n’importe quelle séquence ou générateur dont : str, tuple et range. Voici un exemple sur un tuple.

t = ("Janvier", "Fevrier", "Mars", "Avril", "Mai", "Juin", "Juillet", "Aout", "Septembre", "Octobre", "Novembre", "Decembre")
for i in t :
    print( i )
Janvier
Fevrier
Mars
Avril
Mai
Juin
Juillet
Aout
Septembre
Octobre
Novembre
Decembre

Et un autre exemple sur un range.

for i in range(2,10,2):
    print( i**2 )
4
16
36
64

12.1. Exercices#

Nous allons mettre en oeuvre l’utilisation de boucle « pour chaque ».

Question : Nous souhaitons faire une fonction qui calcule la somme des éléments contenu dans une séquence. Écrire une fonction add qui prend en entrée une séquence de nombres et renvoie la somme des éléments. Tester votre fonction sur une séquence (2, 3, 6, 0.6, 12, -3.3). Attention, il faut donc deux paranthèses. Une pour l’appel de la fonction et une autre pour la séquence.

def add(s):
    pass

add( (2, 3, 6, 0.6, 12, -3.3) )

Voici une correction possible.

def add(s):
    t = 0
    for i in s:
        t += i
    return t  

En pratique, Python dispose d’une fonction sum qui permet de sommer les éléments d’une séquence. On préfèrera faire sum( (2, 3, 6, 0.6, 12, -3.3) ).

Question : Faites une fonction meanqui prend en paramètre une séquence et renvoie la valeur moyenne des termes de la séquences. Testez votre fonction sur la même séquence.

def mean(s):
    pass

mean( (2, 3, 6, 0.6, 12, -3.3) )

Voici une correction possible.

def mean(s):
    return sum(s) / len(s)  

Question : Écrivez une fonction invert qui prend en paramètre une chaine de caractères et renvoie une nouvelle chaine à l’envers. Bonjour donnera ruojnoB.

De manière générale, pour aborder un problème algorithmique, il est souvent plus simple de décomposer en étapes simples. Dans notre cas, il peut être intéressant de commencer par afficher chaque lettre d’une chaine de caractère en commençant du début. Puis en partant de la fin. Et enfin d’accumuler les lettres dans une nouvelle chaine de caractères.

def invert(c):
    pass
        
invert("Bonjour")  

Correction de la première étape

# Affichage des lettres dans l'ordre
def invert(c):
    for i in range(len(c)):
        print(c[i])
        

Correction de la deuxième étape

# Affichage des lettres dans l'ordre inverse on part de -1 
def invert(c):
    for i in range(len(c)):
        print(c[-1-i])
        

Correction de l’étape finale.

# On accumule les lettres dans une chaine de caractères on l'a renvoie à la fin.
def invert(c):
    n = ""
    for i in range(len(c)):
        n += c[-1-i]
    return n

Question : Faites une fonction is_palindrome qui prend en paramètre une chaine de caractère et renvoie True ou False. Un palindrome est un mot qui se lit de la même façon dans les deux sens : kayak, radar.

Indice :

  • Avec range vous pouvez parcourir une chaine de caractères dans un sens et dans l’autre en même temps.

  • Rappelez vous que le mot clef return arrête l’exécution d’une fonction (même si on est dans une boucle).

Besoin d’un indice en plus ? Voici un algorithme qui fonctionne.

On parcours la chaine dans les deux sens à la fois. Dès que l’on trouve une erreur, on s’arrête, on renvoie False. Si après avoir parcouru tous les indices, on n’a pas rencontré d’erreur, on renvoie True.

def is_palindrome( c ):
    pass
    
is_palindrome("ressasser")

Voici une correction possible.

def is_palindrome( c ):
    for i in range(len(c)):
        if c[i] != c[-1-i]:
            return False
    return True 

Question : Sans testez, d’après vous, est-ce que votre fonction is_palindrome fonctionne si on lui donne en entrée une séquence de nombres ?

is_palindrome((2, 3, 6, 0.6, 12, -3.3))

Vérifiez votre réponse, elle pourrait varier selon la manière dont vous avez traiter la question.

Votre fonction devrait fonctionner. En tout cas si vous avez fait quelque chose de similaire au corrigé. C’est normal car les chaines de caractères et les tuples fonctionnent de manière très similaire.

En Python, on ne demande pas que le paramètre d’une fonction soit d’un type en particulier, mais à l’exécution il faudra que toutes les oppérations fonctionnent sans erreur.

Question : On veut maintenant tester également des chaines de caractères contenant des majuscules. Vous pouvez utiliser la fonction upper qui permet de renvoyer une chaine de caractères tout en majuscule. Exemple "Une Chaine".upper() renvoie la valeur UNE CHAINE. Il existe aussi lower.

Faites une fonction is_palindrome2 pour ce cas là.

Voici une correction possible.

def is_palindrome2( c ):
    return is_palindrome( c.upper() )

Question : Que se passe-t-il si vous utilisez la fonction is_palindrome2 sur une séquence de nombre ?

is_palindrome2((2, 3, 6, 0.6, 12, -3.3))

Ici, on ne peut plus utiliser notre fonction avec un tuple car la fonction upper n’existe pas pour les tupples. C’est quelque chose de spécifique aux chaines de caractères.