Tutoriels gratuits et ouverts à toutes et à tous · conçus au Lycée Chevrollier — AngersÀ propos

Série « Parcours Python » · partie 6 / 8

Python niveau 5 — Manipuler des données

Listes, chaînes de caractères et dictionnaires : ranger et exploiter des collections : niveau 5 du parcours Python, avec exercices corrigés et QCM.

Développement✎ B. Jousseaume📅 17 octobre 2026⏱ 6 h📶 Intermédiaire

1. Les listes

Une liste range plusieurs valeurs dans une seule variable, dans un ordre précis. On l’écrit entre crochets.

courses = ["pain", "lait", "œufs"]
notes = [12, 15.5, 9, 17]
vide = []

Accéder aux éléments : les indices

Chaque élément a une position appelée indice, qui commence à 0 (et non 1).

Élément"pain""lait""œufs"
Indice positif012
Indice négatif-3-2-1
print(courses[0])       # pain
print(courses[-1])      # œufs (le dernier)
courses[1] = "beurre"   # on remplace "lait" par "beurre"
print(len(courses))     # 3
print(courses[0:2])     # ['pain', 'beurre'] : tranche de 0 à 2 exclu

Modifier une liste

InstructionEffet
liste.append(x)Ajoute x à la fin
liste.insert(i, x)Insère x à la position i
liste.remove(x)Supprime la première occurrence de x
liste.pop()Retire et renvoie le dernier élément
liste.sort()Trie la liste (sur place)
x in listeTrue si x est dans la liste
sum(l), min(l), max(l)Somme, minimum, maximum

Parcourir une liste

notes = [12, 15.5, 9, 17]

for note in notes:                       # parcours des valeurs
    print(note)

for i in range(len(notes)):              # parcours des indices
    print(f"Note {i + 1} : {notes[i]}")

for i, note in enumerate(notes):         # les deux à la fois
    print(i, note)

2. Les chaînes de caractères, en détail

Une chaîne se comporte comme une liste de caractères : on peut utiliser les indices, les tranches, len() et for. Mais une chaîne est non modifiable : les méthodes renvoient une nouvelle chaîne.

MéthodeExempleRésultat
upper() / lower()"Salut".upper()"SALUT"
strip()" oui ".strip()"oui" (espaces retirés)
replace(a, b)"a-b-c".replace("-", "/")"a/b/c"
split(sep)"a;b;c".split(";")["a", "b", "c"]
sep.join(liste)", ".join(["a", "b"])"a, b"
startswith(x)"Python".startswith("Py")True
count(x)"banane".count("a")3
isdigit()"2026".isdigit()True
ligne = "Dupont;Marie;42"
morceaux = ligne.split(";")      # ['Dupont', 'Marie', '42']
nom, prenom, age = morceaux
print(f"{prenom} {nom.upper()}, {int(age)} ans")
→ Marie DUPONT, 42 ans

3. Les dictionnaires

Un dictionnaire associe des clés à des valeurs, comme un vrai dictionnaire associe un mot à sa définition. On l’écrit entre accolades.

contact = {
    "nom": "Martin",
    "prenom": "Léo",
    "age": 31,
    "ville": "Angers",
}
print(contact["prenom"])          # Léo
contact["age"] = 32               # modification
contact["email"] = "leo@exemple.fr"   # ajout d'une nouvelle clé
del contact["ville"]              # suppression
InstructionEffet
d[cle]Valeur associée (KeyError si la clé n’existe pas)
d.get(cle, defaut)Valeur associée, ou defaut si la clé est absente
cle in dTrue si la clé existe
d.keys(), d.values(), d.items()Les clés, les valeurs, les couples (clé, valeur)
stock = {"pommes": 12, "poires": 0, "kiwis": 30}
for fruit, quantite in stock.items():
    if quantite == 0:
        print(f"{fruit} : RUPTURE")
    else:
        print(f"{fruit} : {quantite}")

Compter avec un dictionnaire

texte = "le chat et le chien et le lapin"
compte = {}
for mot in texte.split():
    compte[mot] = compte.get(mot, 0) + 1
print(compte)
→ {'le': 3, 'chat': 1, 'et': 2, 'chien': 1, 'lapin': 1}

4. Combiner les structures

Les vraies données se représentent souvent comme une liste de dictionnaires : chaque dictionnaire est un enregistrement, la liste est la collection.

eleves = [
    {"nom": "Alice", "note": 14},
    {"nom": "Bruno", "note": 9},
    {"nom": "Chloé", "note": 17},
]
for e in eleves:
    statut = "admis" if e["note"] >= 10 else "non admis"
    print(f"{e['nom']:<8} {e['note']:>5}  {statut}")

La ligne statut = ... if ... else ... est une condition sur une ligne, pratique pour choisir entre deux valeurs. Dans la f-string, :<8 aligne à gauche sur 8 caractères et :>5 à droite sur 5.

5. Mini-projet : le gestionnaire de contacts

6. Bilan

Exercices corrigés

Les structures de données offrent souvent plusieurs solutions valables. Les corrigés privilégient la version la plus lisible pour un débutant, avec des variantes plus « pythoniques » en complément.

Exercice 5.1 — Listes

Voir le corrigé
prenoms = ["Zoé", "Adam", "Lina", "Hugo", "Nina"]
for p in prenoms:
    print(p)
prenoms.append("Émile")
prenoms.sort()
print(prenoms)

def moyenne(liste):
    return sum(liste) / len(liste)

def filtrer_admis(notes):
    admis = []
    for n in notes:
        if n >= 10:
            admis.append(n)
    return admis

mots = []
mot = input("Mot (fin pour arrêter) : ")
while mot != "fin":
    mots.append(mot)
    mot = input("Mot (fin pour arrêter) : ")
plus_long = ""
for m in mots:
    if len(m) > len(plus_long):
        plus_long = m
print(f"Le plus long : {plus_long}")

Explication

filtrer_admis crée une nouvelle liste plutôt que de modifier l’ancienne : c’est plus sûr, car l’appelant garde ses données d’origine. Pour le mot le plus long, on part d’une chaîne vide et on la remplace chaque fois qu’on trouve plus long.

Pour aller plus loin

# Versions compactes
def filtrer_admis(notes):
    return [n for n in notes if n >= 10]

plus_long = max(mots, key=len)

Exercice 5.2 — Chaînes

Voir le corrigé
def est_palindrome(mot):
    mot = mot.lower()
    return mot == mot[::-1]

phrase = input("Phrase : ")
print(f"{len(phrase.split())} mot(s)")

email = input("E-mail : ")
if email.count("@") == 1 and "." in email.split("@")[1]:
    print("Format plausible")
else:
    print("Format invalide")

Explication

mot[::-1] est une tranche avec un pas de -1 : elle parcourt le mot à l’envers. split() sans argument découpe sur les espaces, même multiples. Pour l’e-mail, split("@")[1] donne la partie après l’arobase.

Exercice 5.3 — Répertoire

Voir le corrigé
def meilleur(eleves):
    top = eleves[0]
    for e in eleves:
        if e["note"] > top["note"]:
            top = e
    return top["nom"]

def moyenne_classe(eleves):
    total = 0
    for e in eleves:
        total += e["note"]
    return total / len(eleves)

def chercher(eleves, nom):
    for e in eleves:
        if e["nom"].lower() == nom.lower():
            return e["note"]
    return None

Explication

On parcourt la liste en gardant « le meilleur vu jusqu’ici », comme pour le maximum du niveau 4. chercher renvoie dès qu’elle trouve ; si la boucle se termine, c’est que l’élève n’existe pas.

Pour aller plus loin

def meilleur(eleves):
    return max(eleves, key=lambda e: e["note"])["nom"]

def moyenne_classe(eleves):
    return sum(e["note"] for e in eleves) / len(eleves)

Mini-projet

Voir le corrigé
def ajouter(contacts):
    nom = input("Nom : ").strip()
    if nom.lower() in [n.lower() for n in contacts]:
        print("Ce contact existe déjà.")
        return
    tel = input("Téléphone : ").strip()
    email = input("E-mail : ").strip()
    contacts[nom] = {"tel": tel, "email": email}
    print("Contact ajouté.")

def afficher(contacts):
    if not contacts:
        print("Aucun contact.")
    for nom in sorted(contacts):
        c = contacts[nom]
        print(f"{nom:<15} {c['tel']:<14} {c['email']}")

def rechercher(contacts):
    cherche = input("Nom recherché : ").lower()
    for nom, c in contacts.items():
        if cherche in nom.lower():
            print(f"{nom} : {c['tel']} / {c['email']}")

def supprimer(contacts):
    nom = input("Nom à supprimer : ")
    if nom in contacts:
        del contacts[nom]
        print("Supprimé.")
    else:
        print("Introuvable.")

def main():
    contacts = {}
    while True:
        choix = input("\n1 Ajouter  2 Afficher  3 Rechercher  4 Supprimer  5 Quitter > ")
        if choix == "1":
            ajouter(contacts)
        elif choix == "2":
            afficher(contacts)
        elif choix == "3":
            rechercher(contacts)
        elif choix == "4":
            supprimer(contacts)
        elif choix == "5":
            break

main()

La ligne [n.lower() for n in contacts] est une liste en compréhension : une façon compacte de construire une liste. Elle équivaut à une boucle for avec append.

Explication

Le dictionnaire contacts est créé dans main() puis passé en paramètre à chaque fonction. Comme un dictionnaire est modifiable, les fonctions ajouter et supprimer le modifient directement, sans return. sorted(contacts) renvoie les clés triées.

🧠 Testez vos connaissances

5 questions. Répondez puis cliquez sur « Corriger ». Rien n’est enregistré : c’est de l’auto-évaluation.

1. Quel est l’indice du premier élément d’une liste ?

💬 Les indices vont de 0 à len(liste) - 1. L’indice -1 désigne le dernier élément.

2. Que fait "a;b;c".split(";") ?

💬 join fait l’opération inverse : ";".join(["a", "b"]) donne "a;b".

3. Comment accède-t-on à une valeur dans un dictionnaire ?

💬 contact["prenom"] renvoie la valeur associée à la clé "prenom".

4. Que fait compte[mot] = compte.get(mot, 0) + 1 ?

💬 get renvoie 0 quand la clé n’existe pas encore, ce qui évite l’erreur.

5. Quel critère compte le plus dans la robustesse d’un mot de passe ?

💬 Les recommandations actuelles privilégient la longueur (12 caractères minimum, ou une phrase de passe).

© 2026 Bruno Jousseaume. Ce cours est publié sous licence CC BY-NC-SA 4.0 : vous pouvez le partager et l’adapter en citant l’auteur et un lien vers cette page, sans usage commercial, et en partageant vos adaptations sous la même licence.

Pour aller plus loin