🔄 Le cours : répéter des instructions
Une boucle répète un bloc d'instructions. Python en propose deux : for, quand on parcourt des éléments connus (une liste, un texte, une suite d'entiers), et while, quand on répète tant qu'une condition est vraie sans savoir à l'avance combien de tours il faudra. Dans les deux cas, le bloc répété est indenté sous la ligne d'en-tête qui se termine par :.
La boucle for avec range
range fabrique une suite d'entiers : range(n) va de 0 à n - 1, range(a, b) de a à b - 1, et range(a, b, pas) avance de pas en pas (négatif pour compter à l'envers). La borne de fin est toujours exclue. On voit le contenu avec list(...).
print(list(range(5)))
print(list(range(2, 7)))
print(list(range(0, 20, 5)))
print(list(range(5, 0, -1)))
for i in range(3):
print("tour", i)
Affichage[0, 1, 2, 3, 4]
[2, 3, 4, 5, 6]
[0, 5, 10, 15]
[5, 4, 3, 2, 1]
tour 0
tour 1
tour 2
Parcourir directement les éléments
Un for peut parcourir n'importe quelle séquence : liste, tuple, texte (lettre par lettre), dictionnaire (ses clés). Pour avoir clés et valeurs, on utilise .items(). Parcourir les éléments eux-mêmes évite de manipuler des indices, donc les erreurs d'un cran.
notes = [12, 15, 9]
total = 0
for note in notes:
total += note
print(total)
for lettre in "NSI":
print(lettre)
scores = {"Ada": 18, "Lin": 17}
for nom, note in scores.items():
print(nom, "->", note)
Affichage36
N
S
I
Ada -> 18
Lin -> 17
enumerate et zip
enumerate(liste) donne des couples (indice, valeur) : parfait quand on a besoin de la position, avec start=1 pour numéroter à partir de 1. zip(a, b) parcourt deux séquences en parallèle (il s'arrête à la plus courte).
langages = ["Python", "C", "Java"]
for i, nom in enumerate(langages):
print(i, nom)
for i, nom in enumerate(langages, start=1):
print(f"{i}. {nom}")
prenoms = ["Ada", "Lin"]
notes = [18, 17]
for p, n in zip(prenoms, notes):
print(p, n)
Affichage0 Python
1 C
2 Java
1. Python
2. C
3. Java
Ada 18
Lin 17
La boucle while
while condition: teste la condition avant chaque tour et s'arrête dès qu'elle devient fausse. Il faut donc que le corps de la boucle fasse évoluer quelque chose pour qu'elle finisse un jour. Ici, on additionne les chiffres de 2845 : n % 10 est le dernier chiffre, n //= 10 le retire.
n = 2845
somme = 0
while n > 0:
somme += n % 10
n //= 10
print(somme)
while convient quand on ne connaît pas le nombre de tours : combien d'années faut-il pour doubler un capital placé à 5 % ?
capital = 1000
annees = 0
while capital < 2000:
capital *= 1.05
annees += 1
print(annees, round(capital, 2))
break, continue et else
break quitte immédiatement la boucle, continue abandonne le tour en cours et passe au suivant. Une clause else placée après une boucle s'exécute seulement si la boucle s'est terminée sans break : pratique pour dire « rien trouvé ».
for n in range(10):
if n == 7:
break
if n % 2 == 0:
continue
print(n)
for n in [29, 21]:
for d in range(2, n):
if n % d == 0:
print(n, "= produit de", d, "et", n // d)
break
else:
print(n, "est premier")
Affichage29 est premier
21 = produit de 3 et 7
Autre usage classique de while True : répéter jusqu'à obtenir une réponse valable, puis sortir avec break. Ici, on simule les réponses d'un utilisateur avec une liste.
reponses = ["abc", "", "42"]
i = 0
while True:
saisie = reponses[i]
i += 1
if saisie.isdigit():
break
print("saisie valide :", saisie)
Affichagesaisie valide : 42
Boucles imbriquées
Une boucle peut contenir une autre boucle : pour chaque tour de la boucle extérieure, la boucle intérieure recommence depuis le début. Le nombre de tours se multiplie : n lignes de p cases, c'est n × p tours (voir notations T(n) et O()). print(*ligne) affiche les éléments d'une liste séparés par des espaces.
for i in range(1, 4):
ligne = []
for j in range(1, 4):
ligne.append(i * j)
print(*ligne)
Affichage1 2 3
2 4 6
3 6 9
n = 5
paires = 0
for i in range(n):
for j in range(i + 1, n):
paires += 1
print(paires)
Ici, la boucle intérieure part de i + 1 : on compte les paires (i, j) avec i < j, soit n(n - 1) / 2 paires, un coût en O(n²).
Schémas classiques : accumuler, compter, chercher
| Schéma | Initialisation | Dans la boucle |
| Somme | somme = 0 | somme += x |
| Compteur | nb = 0 | if condition: nb += 1 |
| Maximum | maxi = valeurs[0] | if x > maxi: maxi = x |
| Recherche | trouve = None | if condition and trouve is None: trouve = x |
| Liste résultat | resultat = [] | resultat.append(f(x)) |
valeurs = [4, 8, 15, 16, 23, 42]
somme = 0
nb_pairs = 0
maxi = valeurs[0]
premier_multiple_de_5 = None
for v in valeurs:
somme += v
if v % 2 == 0:
nb_pairs += 1
if v > maxi:
maxi = v
if premier_multiple_de_5 is None and v % 5 == 0:
premier_multiple_de_5 = v
print(somme, nb_pairs, maxi, premier_multiple_de_5)
Compréhensions : construire une liste en une ligne
Une compréhension de liste a la forme [expression for x in sequence if condition] (la partie if est facultative). C'est une boucle for qui construit une liste. Le même principe existe pour les ensembles ({...}), les dictionnaires ({cle: valeur for ...}) et, entre parenthèses, pour des générateurs qui ne fabriquent pas la liste (utiles dans sum, max, any…).
carres = [x * x for x in range(6)]
pairs = [x for x in range(10) if x % 2 == 0]
majuscules = [m.upper() for m in ["nsi", "python"]]
couples = [(i, j) for i in range(2) for j in range(2)]
print(carres)
print(pairs)
print(majuscules)
print(couples)
Affichage[0, 1, 4, 9, 16, 25]
[0, 2, 4, 6, 8]
['NSI', 'PYTHON']
[(0, 0), (0, 1), (1, 0), (1, 1)]
mots = ["chat", "chien", "oiseau"]
longueurs = {m: len(m) for m in mots}
initiales = {m[0] for m in mots}
total = sum(len(m) for m in mots)
print(longueurs)
print(sorted(initiales))
print(total)
Affichage{'chat': 4, 'chien': 5, 'oiseau': 6}
['c', 'o']
15
Combien de tours ?
Pour juger le coût d'une boucle, on compte ses tours : une boucle simple sur n éléments fait n tours (O(n)), deux boucles imbriquées en font n × n (O(n²)), et une boucle qui divise la variable par 2 à chaque tour s'arrête en environ log₂(n) tours.
n = 1000
etapes = 0
while n > 1:
n //= 2
etapes += 1
print(etapes)