Skip to content

Les séquences

Ici, nous allons parler de types qui permettent de stocker une suite d'éléments dans une seule variable.

Il s'agit surtout de définitions à accepter et à savoir. Ce sont des éléments de langage à connaître.

Séquence

Une séquence est une structure de données linéaire qui permet de stocker une suite d'éléments. Ces éléments ont un ordre. On accède à chaque élément de la séquence par son indice.

Sur cette page, nous allons étudier les caractéristiques communes des séquences.

Reconnaître les séquences en python

Types de séquences

Les types de séquences sont les suivants:

  • Chaines de caractères (str)
  • Listes (list)
  • Tuples (tuple)

str

Les str sont les séquences les plus simples. Une chaîne de caractères de taille \(n\) est constituée de caractères numérotés de 0 à \(n-1\).

On les reconnaît graphiquement grâce aux guillemets. Il en existe de 3 types:

s1 = "Hello"
s2 = 'Hello'
s3 = """ Ceci est une chaîne
de caractères multi-lignes """
s4 = "J'ai gagné"

Vous remarquerez qu'on ne peut pas utiliser les simples guillemets pour s4.

tuples

Un tuple de taille \(n\) est constitué de valeurs numérotées de 0 à \(n-1\). Les tuples sont généralement utilisés dans un contexte où on connaît à l'avance le nombre d'éléments qu'on souhaite stocker. On peut y stocker des données hétérogènes (qui ne sont pas du même type).

Voici comment on les reconnaît:

coordonnees : tuple[int, int]      = (5, 0)
personne1   : tuple[str, int, str] = ("Jean", 16, "Paris")
personne2   : tuple[str, int, str] = ("Alice", 18, "Brest")

On les reconnaît généralement à leurs parenthèses, mais en python, ces parenthèses sont facultatives. Ce sont seulement des valeurs séparées par des virgules. Voici des instructions équivalentes aux précédentes:

coordonnees : tuple[int, int]      = 5, 0
personne1   : tuple[str, int, str] = "Jean", 16, "Paris"
personne2   : tuple[str, int, str] = "Alice", 18, "Brest"

Par soucis de clarté, on utilisera toujours les parenthèses.

Attention, le tuple à 1 élément se déclare ainsi:

coordonnees : tuple[int] = (5,)

Si on ne met pas de virgule, python croit qu'on veut simplement mettre 5 en tant qu'int dans la variable coordonnees.

listes

Une liste de taille \(n\) est constituée de valeurs numérotées de 0 à \(n-1\). En python, on peut y stocker des valeurs de type hétérogène, mais on évitera autant que faire se peut. D'ailleurs le système de type de python nous l'impose.

Voici comment on les reconnaît:

notes       : list[float]      = [15, 12, 17, 10.5, 14.5]
prenoms     : list[str]        = ["Alice", "Bob", "Clara"]

Accéder aux éléments d'une séquence

Indices des séquences

Les indices d'une séquence de taille \(n\) sont numérotés de 0 à \(n-1\)

Un indice est un numéro d'élément.

Pour accéder aux éléments d'une séquence, on utilise les crochets.

Pour récupérer l'élément numéro \(i\) d'une séquence seq, on utilise

seq[i]

Voici des exemples pour les 3 types. L'important est de remarquer que c'est toujours la même chose.

mot = "Pikachu"
print(mot[0]) # "P"
print(mot[1]) # "i"
print(mot[2]) # "k"
print(mot[3]) # "a"
print(mot[4]) # "c"
print(mot[5]) # "h"
print(mot[6]) # "u"
print(mot[7]) # -> Lève une IndexError
personne = ("Jean", 16, "Paris")
prenom = personne[0] # "Jean" est affecté à la variable prenom
age    = personne[1] # 16 est affecté à la variable age
ville  = personne[2] # "Paris" est affecté à la variable ville
test   = personne[3] # -> Lève une IndexError

Identiquement pour les listes:

tokens = ["Une", "Séquence", "est", "une", "suite", "d'éléments"]
print(tokens[0]) # "Une"
print(tokens[1]) # "Séquence"
...
print(tokens[5]) # "d'éléments"
print(tokens[6]) # -> Lève une IndexError

Imbrication

tokens = ["Une", "Séquence", "est", "une", "suite", "d'éléments"]

tokens[4] vaut "suite". tokens[4] est donc un str.

tokens[4] est donc une séquence comme les autres, qui se manipule comme les autres, avec des crochets.

Si je veux aller chercher le caractère numéro 2 de tokens[4], je fais tokens[4][2]. Et j'obtiens "i".

L'imbrication n'est pas une fonctionnalité spécifique, c'est juste une conséquence de la syntaxe entre crochets.

Imbrication - Exercice guidé

mots = [
    ["bon", "jour"],
    ["mi", "di"],
    ["chou", "ette"]
]

Questions :

  1. Combien d'éléments a mots ?
  2. Quel est le type complet de mots ?
  3. Affiche le "u" de "jour"
  4. Affiche le "m" de "mi"
  5. Affiche le "u" de "chou"
  6. Affiche la chaîne "chouette" en concaténant deux éléments de mots.

Réponses :

  1. mots a 3 éléments (3 listes internes)
  2. Type complet : list[list[str]] (liste de listes de chaînes)
  3. print(mots[0][1][2]) → affiche "u"
  4. print(mots[1][0][0]) → affiche "m"
  5. print(mots[2][0][2]) → affiche "u"
  6. print(mots[2][0] + mots[2][1]) → affiche "chouette"

Imbrication - Exercice autonome

struct = (
    "root",
    ("A", ["B", "C"], "E"),
    ("F", (4, 9), "J"),
    ("K", (2, "Mot"), ["N", "O"])
)

À vous de faire :

  1. Combien d'éléments a struct ?
  2. Quel est le type complet de struct ?
  3. Affiche "root"
  4. Affiche "J"
  5. Affiche "N"
  6. Affiche le "o" de "Mot"
Solutions
  1. struct a 4 éléments
  2. Type : tuple[str, tuple[str, list[str], str], tuple[str, tuple[int, int], str], tuple[str, tuple[int, str], list[str]]]
  3. print(struct[0])"root"
  4. print(struct[2][2])"J"
  5. print(struct[3][2][0])"N"
  6. print(struct[3][1][1][1])"o"

Mutabilité (capacité à être modifié)

Séquence immuable

Une séquence immuable est une séquence dont la structure de données ne peut pas changer. Toute opération qui dit modifier une séquence renvoie en réalité une nouvelle séquence.

Les tuples et les str sont immuables. Une fois créés, on peut les écraser, mais pas les modifier.

Séquence mutable

Une séquence mutable est une séquence dont la structure de données peut changer. Toute opération qui dit modifier une séquence modifie en RÉALITÉ la séquence.

Les listes sont mutables. Une fois créées, on peut les modifier.

Analogie pour Comprendre

Analogie

  • Un tuple ou un str, c'est comme un texte écrit au stylo : pour corriger, tu dois tout réécrire.
  • Une liste, c'est comme un texte écrit au crayon : tu peux gommer et modifier sur place.

Conséquences sur les str et les tuples

mot = "pikachu"

mot[0] = "P" # Cette instruction renvoie l'erreur ci-dessous

>>> TypeError: 'str' object does not support item assignment
On ne peut pas remplacer "p" par "P". On est obligé de remplacer tout le mot:

mot = "Pikachu"

Les conséquences sont les mêmes sur les tuples

personne = ("Jean", 16, "Paris")

personne[0] = "Bob"  # Cette instruction renvoie l'erreur ci-dessous

>>> TypeError: 'tuple' object does not support item assignment

On ne peut pas remplacer "Jean" par "Bob". On est obligé de remplacer tout le tuple:

personne = ("Bob", 16, "Paris")

Attention

Ici, on utilise le même nom de variable, mais à chaque fois qu'on écrit personne =, ça crée un nouvel emplacement dans la mémoire, et le nom personne y est rattaché.

Conséquences sur les listes

notes = [16, 12, 18]

notes[1] = 12.5

print(notes)

>>> [16, 12.5, 18]

On peut modifier la note de Bob. Ici aucun nouvel emplacement n'est créé en mémoire, et elle est modifiée en place.

Attention

Dès que vous utiliserez = directement sur la variable, le même mécanisme que précédemment s'applique. Un nouvel emplacement mémoire sera créé, donc vous perdrez l'avantage de la mutabilité.


Fonctionnalités communes

Récupérer le nombre d'éléments

On utilise la fonction len(), comme longueur en anglais.

a = [1, 34, 56]
print(len(a))

>>> 3
a = (1, 25, 42, 57)
print(len(a))

>>> 4
a = "abc"
print(len(a))

>>> 3

Appartenance

On utilise la syntaxe in et not in. Ce sont des opérateurs booléens comme les autres.

a = [1, 2, 3]
print(3 in a)  # True
print(4 in a)  # False
print(3 not in a)  # False
print(4 not in a)  # True

Concaténation (+)

a = [1, 2, 3]
b = [4, 5, 6]
c = a + b
print(c)

>>> [1, 2, 3, 4, 5, 6]

Répétition (*)

a = (1, 2, 3)
b = a * 3
print(b)

>>> (1, 2, 3, 1, 2, 3, 1, 2, 3)

Indexation ([]) (vu au début du cours)

a = "xyz"
b = a[1]
print(b)

>>> y

Slice ([:])

Les slices permettent de prendre une partie d'une séquence.

t = ("A", "B", "C", "D", "E", "F")
b = t[1:4]  # de 1 à 4 EXCLUS, donc de 1 à 3
print(b)
>>> ("B", "C", "D")
a = "ABCDEF"
b = a[3:]  # de 3 à la fin (rien après le :)
print(b)
>>> "DEF"
lst = ["A", "B", "C", "D", "E", "F"]
b = lst[:3]  # Du début (rien avant le :) à 3 EXCLUS, donc de 0 à 2
print(b)
>>> ['A', 'B', 'C']

Slices avancés (optionnel)

On peut aussi utiliser un pas (step) pour sauter des éléments :

# Prendre un élément sur deux
lst = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
print(lst[::2])  # Début:Fin:Pas
>>> [0, 2, 4, 6, 8]

# Inverser une séquence
mot = "Python"
print(mot[::-1])
>>> "nohtyP"

⚠️ Erreurs Fréquentes

Voici les erreurs les plus courantes avec les séquences :

Erreur 1 : Index hors limites

# ❌ ERREUR
lst = [1, 2, 3]
print(lst[5])  # IndexError: list index out of range

# ✅ CORRECT
print(lst[2])  # Dernier élément (indice = taille - 1)

Astuce

L'indice maximum est toujours len(seq) - 1 !

Erreur 2 : Modifier un immuable

# ❌ ERREUR
mot = "test"
mot[0] = "T"  # TypeError: 'str' object does not support item assignment

# ✅ CORRECT
mot = "Test"  # Créer un nouveau str
# ❌ ERREUR
coords = (5, 10)
coords[0] = 3  # TypeError: 'tuple' object does not support item assignment

# ✅ CORRECT
coords = (3, 10)  # Créer un nouveau tuple

Erreur 3 : Confusion sur les slices

# ⚠️ ATTENTION
lst = [0, 1, 2, 3, 4]
print(lst[1:4])  
>>> [1, 2, 3]  # Pas [1, 2, 3, 4] !

# L'indice de fin est EXCLUS

Mnémotechnique

[début:fin] signifie : de début INCLUS à fin EXCLUS

Erreur 4 : Confondre indice et valeur

# ❌ ERREUR
notes = [15, 12, 18]
print(notes[15])  # IndexError (15 est une valeur, pas un indice !)

# ✅ CORRECT
print(notes[0])  # 15 (accéder par l'indice)
print(15 in notes)  # True (tester l'appartenance d'une valeur)

Erreur 5 : Oublier que len() compte à partir de 1

lst = [10, 20, 30]
print(len(lst))  # 3

# ❌ ERREUR
print(lst[len(lst)])  # IndexError: list index out of range

# ✅ CORRECT
print(lst[len(lst) - 1])  # 30 (dernier élément)

📚 Pour Aller Plus Loin

Déstructuration (Hors Programme)

Déconstruction

Certains d'entre vous vont tomber sur cette syntaxe, donc je préfère l'expliquer:

a, b, c = 3, 7, 9

Ce qui signifie que les variables a, b et c seront affectées respectivement aux valeurs 3, 7 et 9.

On appelle ça une déstructuration ou déconstruction.

La forme du tuple (3, 7, 9) est comparée à la forme du tuple (a, b, c) et les valeurs 3, 7 et 9 seront affectées respectivement aux variables a, b et c.

Exemple pratique :

personne = ("Alice", 25, "Paris")
nom, age, ville = personne
print(nom)    # "Alice"
print(age)    # 25
print(ville)  # "Paris"

Ça n'est que la partie émergée de l'iceberg.

a, *b = 3, 7, 9
Ce code va affecter a à 3, et le reste (*) dans b, sous forme de liste [7, 9]

premier, *milieu, dernier = [1, 2, 3, 4, 5]
print(premier)  # 1
print(milieu)   # [2, 3, 4]
print(dernier)  # 5

Ce n'est pas une astuce de langage, c'est un outil très puissant dans la résolution de problèmes.


📝 Résumé

Type Exemple Mutable ? Usage
str "Hello" ❌ Non Texte
tuple (1, 2, 3) ❌ Non Données fixes
list [1, 2, 3] ✅ Oui Données modifiables

Opérations communes : - Accès : seq[i] - Longueur : len(seq) - Appartenance : x in seq - Slice : seq[début:fin] - Concaténation : seq1 + seq2 - Répétition : seq * n

À retenir : - Les indices commencent à 0 - Le dernier indice est len(seq) - 1 - Les slices excluent l'indice de fin - Seules les listes sont modifiables

---

Exercices sur les séquences en Python

Exercice 1 : Création et accès

  1. Créer une liste temperatures contenant les températures suivantes : 18.5, 20.0, 19.3, 21.2, 17.8
  2. Afficher la première température
  3. Afficher la dernière température
  4. Afficher la température du milieu (3ème élément)

Exercice 2 : Longueur et indices

  1. Créer un tuple jours contenant : "lundi", "mardi", "mercredi", "jeudi", "vendredi"
  2. Afficher le nombre de jours dans ce tuple
  3. Afficher le jour à l'indice 2
  4. Afficher le dernier jour en utilisant un indice négatif

Exercice 3 : Slicing (tranches)

Soit la liste notes = [12, 15, 8, 14, 16, 11, 13] 1. Extraire les 3 premières notes 2. Extraire les 2 dernières notes 3. Extraire les notes de l'indice 2 à 4 (inclus) 4. Extraire toutes les notes sauf la première et la dernière

Exercice 4 : Modification de listes

  1. Créer une liste fruits = ["pomme", "banane", "orange"]
  2. Remplacer "banane" par "kiwi"
  3. Ajouter "fraise" à la fin de la liste avec .append()
  4. Afficher la liste finale

Exercice 5 : Concaténation

  1. Créer deux listes : nombres1 = [1, 2, 3] et nombres2 = [4, 5, 6]
  2. Créer une nouvelle liste tous_nombres qui combine les deux listes
  3. Afficher le résultat

Exercice 6 : Répétition

  1. Créer une liste contenant 5 fois le nombre 0
  2. Créer un tuple contenant 3 fois la chaîne "NSI"
  3. Afficher les résultats

Exercice 7 : Test d'appartenance

Soit prenoms = ["Alice", "Bob", "Charlie", "David"] 1. Vérifier si "Bob" est dans la liste 2. Vérifier si "Eve" est dans la liste 3. Afficher les résultats avec des messages explicites

Exercice 8 : Min, max, sum

Soit scores = [85, 92, 78, 95, 88] 1. Afficher le score minimum 2. Afficher le score maximum 3. Calculer et afficher la somme des scores 4. Calculer et afficher la moyenne des scores

Exercice 9 : Immuabilité des tuples

  1. Créer un tuple coordonnees = (3, 7)
  2. Essayer de modifier le premier élément (observer l'erreur)
  3. Créer un nouveau tuple nouvelles_coord avec des valeurs différentes
  4. Expliquer dans un commentaire pourquoi on ne peut pas modifier un tuple

Exercice 10 : Mini-projet - Bulletin de notes

Créer un programme qui : 1. Stocke dans une liste les notes suivantes : 14, 16, 12, 15, 13 2. Stocke dans un tuple les coefficients : 1, 2, 1, 1, 2 3. Calcule la moyenne pondérée (sans boucle, en accédant directement aux indices) - Formule : (note0×coef0 + note1×coef1 + ...) / (somme des coefficients) 4. Affiche la moyenne avec un message approprié

Fonctions avec des séquences

Utiliser les doctests (tests unitaires automatiques)

Mettez le code suivant à la fin de votre fichier:

if __name__ == "__main__":
    import doctest
    doctest.testmod()  # Exécute tous les doctests

Il permet d'exécuter automatiquement les doctests lorsque vous exécutez le programme python.

Les doctests sont les instructions précédées de >>> dans la docstring.

Le code suivant veut dire que quand on exécutera premier_element([18.5, 20.0, 19.3]), on attend que la fonction renvoie 18.5

>>> premier_element([18.5, 20.0, 19.3])
18.5

Si le test est passant (il marche), alors python ne dira rien du tout. Sinon il râle.

Dans le code que je vous fournis, j'annule l'exécution des doctests en indiquant # doctest: +SKIP

Ca vous permet de copier coller tout le texte d'un exercice, et d'activer les doctests de la fonction sur laquelle vous travaillez en supprimant # doctest: +SKIP

Exercice 1 : Fonctions d'accès aux éléments

Écrire les fonctions suivantes :

def premier_element(sequence: list) -> int | float | str:
    """Renvoie le premier élément d'une séquence

    >>> premier_element([18.5, 20.0, 19.3])     # doctest: +SKIP
    18.5
    >>> premier_element(['a', 'b', 'c'])     # doctest: +SKIP
    'a'
    """
    pass

def dernier_element(sequence: list) -> int | float | str:
    """Renvoie le dernier élément

    >>> dernier_element([18.5, 20.0, 19.3])     # doctest: +SKIP
    19.3
    >>> dernier_element([1, 2, 3, 4, 5])     # doctest: +SKIP
    5
    """
    pass

def element_milieu(sequence: list) -> int | float | str:
    """Renvoie l'élément du milieu (longueur impaire)

    >>> element_milieu([18.5, 20.0, 19.3, 21.2, 17.8])     # doctest: +SKIP
    19.3
    >>> element_milieu([1, 2, 3])     # doctest: +SKIP
    2
    """
    pass

Exercice 2 : Fonctions de vérification

Écrire les fonctions suivantes :

def est_vide(sequence: list | tuple) -> bool:
    """Renvoie True si la séquence est vide, False sinon

    >>> est_vide([])     # doctest: +SKIP
    True
    >>> est_vide([1, 2, 3])     # doctest: +SKIP
    False
    >>> est_vide(())     # doctest: +SKIP
    True
    """
    pass

def longueur_paire(sequence: list | tuple) -> bool:
    """Renvoie True si la longueur est paire

    >>> longueur_paire([1, 2, 3, 4])     # doctest: +SKIP
    True
    >>> longueur_paire([1, 2, 3])     # doctest: +SKIP
    False
    >>> longueur_paire([])     # doctest: +SKIP
    True
    """
    pass

def contient(sequence: list | tuple, element: int | float | str) -> bool:
    """Renvoie True si l'élément est dans la séquence

    >>> contient([1, 2, 3], 2)     # doctest: +SKIP
    True
    >>> contient([1, 2, 3], 5)     # doctest: +SKIP
    False
    >>> contient(['a', 'b', 'c'], 'b')     # doctest: +SKIP
    True
    """
    pass

Exercice 3 : Fonctions de découpage

Écrire les fonctions suivantes :

def trois_premiers(sequence: list) -> list:
    """Renvoie les 3 premiers éléments

    >>> trois_premiers([12, 15, 8, 14, 16, 11, 13])     # doctest: +SKIP
    [12, 15, 8]
    >>> trois_premiers([1, 2, 3, 4, 5])     # doctest: +SKIP
    [1, 2, 3]
    """
    pass

def deux_derniers(sequence: list) -> list:
    """Renvoie les 2 derniers éléments

    >>> deux_derniers([12, 15, 8, 14, 16, 11, 13])     # doctest: +SKIP
    [11, 13]
    >>> deux_derniers([1, 2, 3, 4, 5])     # doctest: +SKIP
    [4, 5]
    """
    pass

def sans_extremes(sequence: list) -> list:
    """Renvoie la séquence sans le premier et le dernier élément

    >>> sans_extremes([12, 15, 8, 14, 16, 11, 13])     # doctest: +SKIP
    [15, 8, 14, 16, 11]
    >>> sans_extremes([1, 2, 3, 4])     # doctest: +SKIP
    [2, 3]
    """
    pass

Exercice 4 : Fonctions de statistiques simples

Écrire les fonctions suivantes :

def minimum(sequence: list[int | float]) -> int | float:
    """Renvoie le plus petit élément

    >>> minimum([85, 92, 78, 95, 88])     # doctest: +SKIP
    78
    >>> minimum([3.5, 2.1, 4.8])     # doctest: +SKIP
    2.1
    """
    pass

def maximum(sequence: list[int | float]) -> int | float:
    """Renvoie le plus grand élément

    >>> maximum([85, 92, 78, 95, 88])     # doctest: +SKIP
    95
    >>> maximum([3.5, 2.1, 4.8])     # doctest: +SKIP
    4.8
    """
    pass

def etendue(sequence: list[int | float]) -> int | float:
    """Renvoie la différence entre le max et le min

    >>> etendue([85, 92, 78, 95, 88])     # doctest: +SKIP
    17
    >>> etendue([10, 20, 30])     # doctest: +SKIP
    20
    """
    pass

def moyenne(sequence: list[int | float]) -> float:
    """Calcule la moyenne des éléments

    >>> moyenne([85, 92, 78, 95, 88])     # doctest: +SKIP
    87.6
    >>> moyenne([10, 20, 30])     # doctest: +SKIP
    20.0
    """
    pass

Exercice 5 : Fonctions de création

Écrire les fonctions suivantes :

def creer_liste_zeros(n: int) -> list[int]:
    """Renvoie une liste de n zéros

    >>> creer_liste_zeros(5)     # doctest: +SKIP
    [0, 0, 0, 0, 0]
    >>> creer_liste_zeros(3)     # doctest: +SKIP
    [0, 0, 0]
    """
    pass

def creer_liste_constante(n: int, valeur: int | float | str) -> list:
    """Renvoie une liste de n fois la même valeur

    >>> creer_liste_constante(4, 7)     # doctest: +SKIP
    [7, 7, 7, 7]
    >>> creer_liste_constante(3, 'NSI')     # doctest: +SKIP
    ['NSI', 'NSI', 'NSI']
    """
    pass

def concatener(seq1: list, seq2: list) -> list:
    """Renvoie la concaténation de deux séquences

    >>> concatener([1, 2, 3], [4, 5, 6])     # doctest: +SKIP
    [1, 2, 3, 4, 5, 6]
    >>> concatener(['a', 'b'], ['c', 'd'])     # doctest: +SKIP
    ['a', 'b', 'c', 'd']
    """
    pass

Exercice 6 : Fonctions de modification

Écrire les fonctions suivantes :

def remplacer_premier(liste: list, nouvelle_valeur: int | float | str) -> list:
    """Remplace le premier élément et renvoie la liste modifiée

    >>> remplacer_premier([1, 2, 3], 10)     # doctest: +SKIP
    [10, 2, 3]
    >>> remplacer_premier(['a', 'b', 'c'], 'z')     # doctest: +SKIP
    ['z', 'b', 'c']
    """
    pass

def remplacer_dernier(liste: list, nouvelle_valeur: int | float | str) -> list:
    """Remplace le dernier élément

    >>> remplacer_dernier([1, 2, 3], 10)     # doctest: +SKIP
    [1, 2, 10]
    >>> remplacer_dernier(['a', 'b', 'c'], 'z')     # doctest: +SKIP
    ['a', 'b', 'z']
    """
    pass

def ajouter_element(liste: list, element: int | float | str) -> list:
    """Ajoute un élément à la fin et renvoie la liste

    >>> ajouter_element([1, 2, 3], 4)     # doctest: +SKIP
    [1, 2, 3, 4]
    >>> ajouter_element(['a', 'b'], 'c')     # doctest: +SKIP
    ['a', 'b', 'c']
    """
    pass

Exercice 7 : Fonctions de comparaison

Écrire les fonctions suivantes :

def meme_longueur(seq1: list | tuple, seq2: list | tuple) -> bool:
    """Renvoie True si les deux séquences ont la même longueur

    >>> meme_longueur([1, 2, 3], [4, 5, 6])     # doctest: +SKIP
    True
    >>> meme_longueur([1, 2], [3, 4, 5])     # doctest: +SKIP
    False
    >>> meme_longueur((1, 2), [3, 4])     # doctest: +SKIP
    True
    """
    pass

def plus_longue(seq1: list, seq2: list) -> list:
    """Renvoie la séquence la plus longue

    >>> plus_longue([1, 2, 3], [4, 5])     # doctest: +SKIP
    [1, 2, 3]
    >>> plus_longue([1], [2, 3, 4, 5])     # doctest: +SKIP
    [2, 3, 4, 5]
    """
    pass

def ont_element_commun(seq1: list, seq2: list) -> bool:
    """Renvoie True si au moins un élément est présent dans les deux séquences

    >>> ont_element_commun([1, 2, 3], [3, 4, 5])     # doctest: +SKIP
    True
    >>> ont_element_commun([1, 2], [3, 4])     # doctest: +SKIP
    False
    >>> ont_element_commun(['a', 'b'], ['b', 'c'])     # doctest: +SKIP
    True
    """
    pass

Exercice 8 : Fonctions avec indices

Écrire les fonctions suivantes :

def element_a_position(sequence: list, position: int) -> int | float | str | None:
    """Renvoie l'élément à la position donnée, None si position invalide

    >>> element_a_position([10, 20, 30, 40], 2)     # doctest: +SKIP
    30
    >>> element_a_position([10, 20, 30], 5)     # doctest: +SKIP

    >>> element_a_position(['a', 'b', 'c'], 0)     # doctest: +SKIP
    'a'
    """
    pass

def echanger_extremes(liste: list) -> list:
    """Échange le premier et le dernier élément

    >>> echanger_extremes([1, 2, 3, 4, 5])     # doctest: +SKIP
    [5, 2, 3, 4, 1]
    >>> echanger_extremes(['a', 'b', 'c'])     # doctest: +SKIP
    ['c', 'b', 'a']
    """
    pass

def inverser_paire(liste: list) -> list:
    """Inverse les deux premiers éléments

    >>> inverser_paire([1, 2, 3, 4])     # doctest: +SKIP
    [2, 1, 3, 4]
    >>> inverser_paire(['a', 'b', 'c'])     # doctest: +SKIP
    ['b', 'a', 'c']
    """
    pass

Exercice 9 : Fonctions de validation

Écrire les fonctions suivantes :

def tous_positifs(sequence: list[int | float]) -> bool:
    """Vérifie que tous les nombres sont positifs

    >>> tous_positifs([1, 2, 3, 4])     # doctest: +SKIP
    True
    >>> tous_positifs([1, -2, 3])     # doctest: +SKIP
    False
    >>> tous_positifs([0, 5, 10])     # doctest: +SKIP
    True
    """
    pass

def au_moins_un_negatif(sequence: list[int | float]) -> bool:
    """Vérifie s'il y a au moins un nombre négatif

    >>> au_moins_un_negatif([5, -3, 12, 8])     # doctest: +SKIP
    True
    >>> au_moins_un_negatif([1, 2, 3])     # doctest: +SKIP
    False
    >>> au_moins_un_negatif([0, -1, 5])     # doctest: +SKIP
    True
    """
    pass

def dans_intervalle(sequence: list[int | float], min_val: int | float, max_val: int | float) -> bool:
    """Vérifie que tous les éléments sont entre min_val et max_val

    >>> dans_intervalle([5, 8, 12, 15], 0, 20)     # doctest: +SKIP
    True
    >>> dans_intervalle([5, -3, 12], 0, 20)     # doctest: +SKIP
    False
    >>> dans_intervalle([10, 12, 15], 10, 15)     # doctest: +SKIP
    True
    """
    pass

Exercice 11 : Fonctions avancées - Coordonnées 2D

Créer un système de gestion de points dans un plan :

def creer_point(x: float, y: float) -> tuple[float, float]:
    """Crée un point sous forme de tuple (x, y)

    >>> creer_point(3.0, 4.0)     # doctest: +SKIP
    (3.0, 4.0)
    >>> creer_point(-2.5, 1.5)     # doctest: +SKIP
    (-2.5, 1.5)
    """
    pass

def abscisse(point: tuple[float, float]) -> float:
    """Renvoie l'abscisse du point

    >>> abscisse((3.0, 4.0))     # doctest: +SKIP
    3.0
    >>> abscisse((-2.5, 1.5))     # doctest: +SKIP
    -2.5
    """
    pass

def ordonnee(point: tuple[float, float]) -> float:
    """Renvoie l'ordonnée du point

    >>> ordonnee((3.0, 4.0))     # doctest: +SKIP
    4.0
    >>> ordonnee((-2.5, 1.5))     # doctest: +SKIP
    1.5
    """
    pass

def distance_origine(point: tuple[float, float]) -> float:
    """Calcule la distance du point à l'origine

    >>> distance_origine((3.0, 4.0))     # doctest: +SKIP
    5.0
    >>> distance_origine((0.0, 0.0))     # doctest: +SKIP
    0.0
    """
    # Utiliser la formule: racine(x² + y²)
    pass

def milieu(point1: tuple[float, float], point2: tuple[float, float]) -> tuple[float, float]:
    """Calcule le point milieu entre deux points

    >>> milieu((0.0, 0.0), (4.0, 6.0))     # doctest: +SKIP
    (2.0, 3.0)
    >>> milieu((1.0, 2.0), (3.0, 4.0))     # doctest: +SKIP
    (2.0, 3.0)
    """
    pass

def creer_rectangle(point1: tuple[float, float], point2: tuple[float, float]) -> list[tuple[float, float]]:
    """Crée une liste de 4 points formant un rectangle

    >>> creer_rectangle((0.0, 0.0), (2.0, 3.0))     # doctest: +SKIP
    [(0.0, 0.0), (2.0, 0.0), (2.0, 3.0), (0.0, 3.0)]
    """
    # Les deux points donnés sont des coins opposés
    pass

Exercice 12 : Fonctions de formatage

Écrire les fonctions suivantes :

def formater_liste(sequence: list) -> str:
    """Renvoie une chaîne du type: '[elem1, elem2, elem3]'

    >>> formater_liste([1, 2, 3])     # doctest: +SKIP
    '[1, 2, 3]'
    >>> formater_liste(['a', 'b'])     # doctest: +SKIP
    '[a, b]'
    """
    pass

def creer_email(prenom: str, nom: str, domaine: str) -> str:
    """Crée une adresse email

    >>> creer_email("Jean", "Dupont", "lycee.fr")     # doctest: +SKIP
    'jean.dupont@lycee.fr'
    >>> creer_email("Marie", "Martin", "ecole.org")     # doctest: +SKIP
    'marie.martin@ecole.org'
    """
    # Penser à utiliser .lower() pour mettre en minuscules
    pass

Exercice 13 : Fonctions avec tuples de taille fixe

def creer_date(jour: int, mois: int, annee: int) -> tuple[int, int, int]:
    """Crée un tuple représentant une date

    >>> creer_date(15, 3, 2024)     # doctest: +SKIP
    (15, 3, 2024)
    >>> creer_date(1, 1, 2000)     # doctest: +SKIP
    (1, 1, 2000)
    """
    pass

def jour_de(date: tuple[int, int, int]) -> int:
    """Extrait le jour d'une date

    >>> jour_de((15, 3, 2024))     # doctest: +SKIP
    15
    >>> jour_de((1, 12, 2023))     # doctest: +SKIP
    1
    """
    pass

def mois_de(date: tuple[int, int, int]) -> int:
    """Extrait le mois d'une date

    >>> mois_de((15, 3, 2024))     # doctest: +SKIP
    3
    >>> mois_de((1, 12, 2023))     # doctest: +SKIP
    12
    """
    pass

def annee_de(date: tuple[int, int, int]) -> int:
    """Extrait l'année d'une date

    >>> annee_de((15, 3, 2024))     # doctest: +SKIP
    2024
    >>> annee_de((1, 12, 2023))     # doctest: +SKIP
    2023
    """
    pass

def date_valide(date: tuple[int, int, int]) -> bool:
    """Vérifie si une date est valide (jours entre 1-31, mois entre 1-12)

    >>> date_valide((15, 3, 2024))     # doctest: +SKIP
    True
    >>> date_valide((32, 1, 2024))     # doctest: +SKIP
    False
    >>> date_valide((15, 13, 2024))     # doctest: +SKIP
    False
    >>> date_valide((0, 5, 2024))     # doctest: +SKIP
    False
    """
    pass