Liste et autres types séquences
Chapitre en cours de relecture
Ce chapitre manque quelques exercices et corrections mineures. Vous pouvez vous y attaquer, mais il faudra y revenir plus tard quand les exercices auront étés ajoutés.
Ce chapitre est également trop détaillé, il doit subir une réécriture.
Le but d'un programme est en général de manipuler des données multiples, voir massives. Par exemple, les centaines d'images qui constituent une vidéo.
Et bien entendu, les langages de programmation nous donnent des outils pour organiser ces données multiples : les structures de données.
Dans ce chapitre, vous allez faire un programme qui calcule votre moyenne. D'abord très simplement, puis de plus en plus efficacement !
Les listes
La liste est sans doute le structure de données la plus intuitive. Elle range des données de meme type, dans un ordre donné. En python, la liste est implémentée dans le type list.
Ca ressemble vraiment beaucoup à une liste que l'on fait dans la vie de tous les jours
Les ambiguités des termes
Parfois, les listes sont appelées "tableaux". Ca dépends des langages et des ouvrages de la littératures.
Dans le programme scolaire de NSI, on demande d'utiliser "tableaux", mais aussi ... de respecter la terminologie de Python (donc "list" ou "liste")...
Ici, j'utiliserai list ou liste, et rarement tableau.
Rappelez-vous juste que en général, quand on parle de "tableau" en programmation, ça corresponds au type list en Python.
On crée une liste vide en utilisant [] :
notes = [] # crée une liste vide (sans élément)
notes_math = [10, 2, 19] # crée une liste contenant 10, 2, et 19, dans cet ordre
On peut ensuite ajouter des éléments à la fin d'une liste en utilisant la méthode append :
notes = [] # crée une liste vide
notes.append(12) # notes vaut [12]
notes.append(17) # notes vaut [12, 17]
notes.append(15) # notes vaut [12, 17, 15]
On peut connaître le nombre d'éléments dans une liste avec len:
Pour accédér au Nième élément d'une liste, on utilise l'opérateur [] :
HEIN QUOI ? 17 ? MAIS VOUS AVEZ PÉTÉ UN CÂBLE MONSIEUR, c'est 12 !
Non j'ai rien pété du tout, c'est juste que en Python, et dans la majorité des langages de programmation, on commence à compter les éléments d'une liste à partir de 0 :
Finalement, on peut parcourir une liste, en utilisant une boucle for:
Calcul de moyenne : le début
TODO Ici faire un programme qui permet de calculer sa moyenne, avec eventuellement de extensions : moyenne pondérée etc. Mentionner en GROS que le précédent cours est sur les FONCTIONS. histoire de les faire découper.
Pour petit rappel, le chapitre précédent traitait des fonctions. J'insiste :
Voilà, c'est dit, on passe au sujet ?
Activité : calculateur de moyenne
Ecrivez un programme python qui demande des notes à l'utilisateur tant que l'utilisateur n'entre pas une note négative, puis affiche la moyenne des notes positives entrées.
Par exemple :
J'ai vraiment besoin de le redire ? Sérieusement ?
Essayez de découper votre code en fonctions :
- Demander les notes
- Calcul de la moyenne
- Affichage de la moyenne
Demander les notes :
Partez d'une liste vide, puis ajoutez les notes une par une en les demandant !
Eventuellement, commencez par demander un nombre fixe de notes si c'est plus simple :
Calcul de la moyenne :
faites la somme des notes avec une boucle for.
Puis divisez par le nombre de notes.
def demander_notes():
note = 0
notes = []
while note >= 0:
note = float(input("Entrez une note : "))
if note >= 0:
notes.append(note)
return notes
def moyenne(notes):
somme = 0
for note in notes :
somme += note
return somme / len(notes)
def afficher_moyenne(moyenne):
print("moyenne :", moyenne)
notes = demander_notes()
moy = moyenne(notes)
afficher_moyenne(moy)
Types séquences
Les listes font partie de la famille des séquences, c'est à dire des structures de données qui retiennent des valeurs dans un ordre donné.
Il y a d'autres types séquences en Python, qui sont bien entendu le sujet de la suite de ce chapitre.
Les types séquences se manipulent plus ou moins de la même manière, ce qui va beaucoup alléger le chapitre.
Str, chaines de caractères
Vous avez déjà manipulé des chaines de caractères (type str). Si si, vous savez, entre guillemets :
Les chaines de caractères sont composées de caractères, dans un ordre donné.
On crée une chaine de caractères avec "" :
Pour le reste, c'est presque comme les listes :
On peut accéder à un caractère de la chaîne avec [], comme pour une liste :
une_chaine = "abcdef"
premier_car = une_chaine[0] #ca commence à 0, comme les listes !
deuxieme_car = une_chaine[1]
troisieme_car = une_chaine[2]
On peut connaître la longueur d'une chaîne en utilisant len :
On peut parcourir une chaine à l'aide d'une boucle for :
une_chaine = "abcdef"
for car in une_chaine:
print(car) #affiche successivement a, b, c, d, e, et f.
Il y a quand même des différences :
On ne peut pas append un caractère à une chaine, mais on peut concaténer deux chaines avec + :
A noter que ca marche aussi pour les listes :
Aussi, on peut découper une chaîne de caractères à l'aide de split :
Activité : expérimentation rapide
Exécutez le bout de code suivant dans un fichier à part :
Expliquez ce que fait split ?
Quel est le type de la valeur retournée par split ?
split découpe une chaîne de caractères sur un caractère.
La valeur retournée par split est une liste de chaines.
Calcul de moyenne : toutes les notes d'un coup
Activité : toutes les notes d'un coup
Modifiez le programme de calcul de moyenne pour que, au lieu que l'utilisateur entre les notes une par une, il les rentre toutes en une fois, séparées par des virgules.
Par exemple :
Vous devez séparer la chaine, puis convertir chaque élément en nombre.
Si comme je vous avais dit, vous avez
Normalement, vous n'avez qu'a modifier la fonction demander_notes :
def demander_notes():
notes = input("entrez les notes : ")
notes_chaines = notes.split(",")
notes_nombres = []
for note in notes_chaines:
notes_nombres.append(float(note))
return notes_nombres
Magique, non ?
Parcours avec while
Parfois, la boucle for n'est pas suffisante pour parcourir une liste (ou un autre type séquence).
Dans ce cas, on utilise une boucle while, de la forme suivante :
Toute boucle for peut-être transformé en while, mais l'inverse n'est pas vrai !
Activité : de for à While
Transformez la boucle for suivante en un while
Calcul de moyenne : coefficients
Activité : coefficients
Modifiez le programme de calcul de moyenne pour que l'utilisateur puisse spécifier les coefficients de chaque note.
Par exemple :
Je vous ai déjà dit de
il me semble...
Essayez de faire ça sur du papier... Ca va vous aider.
Si vous ne voyez pas comment faire, appelez votre prof !
On écrit une nouvelle fonction demander_coefficients, qui est presque un copier-coller de demander_notes :
def demander_coefficients():
coefs = input("entrez les coefficients : ")
coefs_chaines = coefs.split(",")
coefs_nombres = []
for coef in coefs_chaines:
coefs_nombres.append(float(coef))
return coefs_nombres
Ensuite, on modifie moyenne pour qu'elle calcule avec les coefs. Pour ça, on a besoin d'une boucle while, pour parcourir à la fois
notes et coefs :
def moyenne(notes, coefs):
somme = 0
somme_coefs = 0
i = 0
while i < len(notes):
somme += notes[i] * coefs[i]
somme_coefs += coefs
return somme / somme_coefs
Finalement, on adapte le reste du code :
Quel est le gros défaut de cette solution ?
Que se passe-t-il si on essaie de rentrer beaucoup de notes ?
Le gros défaut de cette solution est que les coefficients ne sont pas directement entrés avec les notes. Ca peut être source de confusion pour l'utilisateur.
On va essayer d'améliorer ça.
Tuple, les... t-uplets
Une paire, association de deux éléments, est un 2-uplet : (1, 2)
Un triplet, association de trois éléments, est un 3-uplet : (1, 2, 4)
Un quadruplet, association de quatre éléments, est un 4-uplet : (1, 2, 4, 0)
Si on généralise le concept à un nombre arbitraire t d'éléments, on obtient un t-uplet. En Python, ça corresponds au type tuple.
Pour créer un tuple, on utilise des parenthèses ().
Pour le reste, c'est presque comme les listes :
On peut accéder à un élémént d'un tuple avec [], comme pour une liste :
On peut connaître la longueur d'un tuple en utilisant len :
On peut parcourir un tuple à l'aide d'une boucle for :
Il y a quand même des différences :
Comme pour les chaînes, on ne peut pas append un élément à un tuple, mais on peut concaténer deux tuples avec + :
tuple_1 = (1, 2, 3)
tuple_2 = ("a", "b", "c")
tuple_3 = tuple_1 + tuple_2 #vaut (1, 2, 3, "a", "b", "c")
Ici, vous avez probablement l'impression que les tuples sont juste des listes en moins bien.
En réalité, ils ont d'autres différences que l'on verra dans les chapitres suivants.
Mais la plus important est leur usage sémantique.
Sémantique ?
La sémantique, c'est la manière dont le sens de notre code est défini.
Activité : tuple vs liste
Pour stocker les données représentant un élève, on utilise généralement un tuple :
Pour stocker une paire de coordonnées en 2D, on utilise généralement un tuple :
Pour stocker des notes, on utilise généralement une liste :
Essayez de comprendre les raisons qui dictent le choix d'un tuple ou d'une liste.
Quand vous pensez avoir trouvé, appelez votre prof pour en discuter.
Essayez de représenter d'autres personnes...
D'autres ensemble de notes...
Et observez la forme qu'a les données.
Un tuple est généralement utilisé pour manipuler un ensemble de données :
- de taille fixe (et généralement réduite)
- où les différents éléments ont des significations différentes, données par leur position
dans un tuple, on s'autorise à avoir des élements de types différents :
Une liste est généralement utilisée pour manipuler un ensemble de données :
- de taille variable
- où tous les éléments ont la même signification
dans une liste, on s'impose d'avoir un seul et même type pour tous les éléments :
Activité : structuration
Cette activité à pour but de vous faire réfléchir sur l'utilisation de tuples et de listes.
A chaque question est présentée une bonne réponse. Si vous avez une réponse différente, elle n'est pas forcément fausse, demandez un avis à votre prof.
Comment représenter les données d'une classe, avec le nom, le prénom, et la moyenne de chaque élève ?
Chaque élève a un nom, un prénom et une moyenne. C'est un ensemble de taille fixe, où chaque élément à une signification différente. On utilise donc un tuple.
Une classe est un ensemble d'élèves, dont le nombre peut varier. On utilise donc une liste.
Une classe est alors représentée ainsi :
Calcul de moyenne : notes et coefs, tout d'un coup
Activité : notes et coefs, tout d'un coup
Modifiez le programme de calcul de moyenne pour que l'utilisateur puisse rentrer les notes et les coefficients en une seule fois, tout en gardant chaque coefficient proche de la note correspondante.
Par exemple :
Cette activité est relativement difficile. Prenez votre temps et n'hésitez pas à demander de l'aide en cas de blocage.
Commencez par trouver comment structurer les notes et les coefficients.
Il vous faut d'abord séparer chaque paire de note et coef
puis séparer chaque note et son coef
Et n'oubliez-pas :
Ainsi font font font,
Ainsi font font font,
Les petites
On va représenter les notes comme suit :
On commence par modifier la fonction demander_notes. C'est le gros du travail.
Pour plus de clareté on se crée une fonctions separer_note_coef :
def separer_note_coef(chaine):
note_coef = chaine.split("/")
return (float(note_coef[0]), float(note_coef[1]))
def demander_notes():
notes_chaine = input("Entrez les notes : ")
notes_chaines_sep = notes_chaine.split(",") #on sépare les paires
notes = []
for chaine in notes_chaines_sep:
notes.append(separer_note_coef(chaine)) #on sépare chaque paire
return notes
On peut alors supprimer demander_coefficients, la fonction n'est plus utile.
Ensuite, on adapte la fonction moyenne à cette nouvelle structure :
def moyenne(notes):
somme = 0
somme_coefs = 0
for note in notes : #note est un tuple (note, coef)
somme += note[0] * note[1] #note[0] la note, note[1] le coef
somme_coefs += note[1]
return somme / somme_coefs
Pour terminer, on modifie le reste du code :
Sucre syntaxique
TODO : fonction map, zip, unpacking...