madamasterclass.com

📔 Listes en python

Connaître la notion de Liste en Python

1. Les listes Python : Structure fondamentale
🧩 Qu'est-ce qu'une liste ?

Une liste en Python est une structure de données fondamentale qui permet de stocker une collection ordonnée et modifiable d'éléments. Contrairement aux tableaux de certains langages, les listes Python peuvent contenir des éléments de types différents au sein de la même structure.

[éléments séparés par des virgules]
0 1 2 3 42 "Python" 3.14 True
ma_liste = [42, "Python", 3.14, True] # Types variés
🔍 Caractéristiques clés

Les listes Python possèdent plusieurs propriétés fondamentales qui les distinguent des autres structures de données :

1️⃣ Ordonnée : Les éléments conservent leur position d'insertion. L'indexation commence à 0 et suit la formule \(index = position - 1\)
2️⃣ Mutable : La liste peut être modifiée après sa création (ajout, suppression, modification d'éléments)
3️⃣ Hétérogène : Peut contenir des éléments de types différents (entiers, chaînes, booléens, objets)
4️⃣ Dynamique : La taille peut varier pendant l'exécution du programme
print(ma_liste[1]) # → "Python" (accès par index) print(len(ma_liste)) # → 4 (longueur de la liste)
📚 Complexité temporelle des opérations de base :

La compréhension de la complexité est cruciale pour optimiser les performances :

  • • Accès par index : \(O(1)\) - temps constant
  • • Ajout en fin : \(O(1)\) amortisé
  • • Insertion au début : \(O(n)\) - tous les éléments doivent être décalés
  • • Recherche d'un élément : \(O(n)\) - parcours linéaire
2. Opérations essentielles et leur impact
➕ Opérations d'ajout

Les opérations d'ajout permettent d'étendre dynamiquement la liste. Chaque méthode a ses spécificités :

append(x) : Ajoute x à la fin
insert(i, x) : Insère x à l'index i
extend(iterable) : Ajoute tous les éléments
1 2 3 4 append(4)
➖ Opérations de suppression

La suppression d'éléments peut affecter les indices des éléments suivants. Il est important de comprendre les différences :

remove(x) : Supprime la 1ère occurrence de x
pop(i) : Supprime et retourne l'élément à l'index i
del liste[i] : Supprime l'élément à l'index i
1 2 3 4 remove(2)
🔁 Opérations combinatoires

Python offre des opérateurs intuitifs pour combiner et manipuler les listes de manière élégante :

liste1 + liste2 : Concaténation
liste * n : Répétition n fois
x in liste : Test d'appartenance
1 2 + 3 4 1 2 3 4 [1,2] + [3,4] = [1,2,3,4]
💻 Exemple complet avec analyse :
nombres = [5, 2, 8]                # Initialisation - O(1)
nombres.append(1)                      # [5, 2, 8, 1] - O(1) amortisé
nombres.insert(1, 4)                   # [5, 4, 2, 8, 1] - O(n)
dernier = nombres.pop()               # [5, 4, 2, 8], dernier = 1 - O(1)
doubles = nombres + nombres           # [5, 4, 2, 8, 5, 4, 2, 8] - O(n)
triples = nombres * 3              # Répétition 3 fois - O(n)
contient_4 = 4 in nombres        # True - O(n)
3. Méthodes avancées et algorithmes intégrés
🔧 Méthodes de manipulation avancées

Python propose des méthodes sophistiquées pour manipuler les listes efficacement :

sort(key=None, reverse=False) Tri sur place avec critère personnalisé
reverse() Inversion de l'ordre des éléments
count(x) Nombre d'occurrences de x
index(x, start, end) Index de la première occurrence de x
copy() Copie superficielle de la liste
clear() Supprime tous les éléments
# Tri personnalisé avec complexité O(n log n)
mots = ["Python", "est", "formidable"]
mots.sort(key=len) # Tri par longueur
# Résultat:
["est", "Python", "formidable"]
📊 Visualisation des algorithmes

Comprendre visuellement le comportement des algorithmes de tri et de recherche :

Tri croissant (Timsort - O(n log n)) 8 3 1 6 Avant 1 3 6 8 Après Inversion (reverse - O(n)) A B C D D C B A Échange des éléments symétriques
🧮 Algorithmes de tri intégrés :

Python utilise l'algorithme Timsort, un algorithme hybride dérivé de merge sort et insertion sort. Sa complexité temporelle est :

  • • Meilleur cas : \(O(n)\) - liste déjà triée
  • • Cas moyen : \(O(n \log n)\) - ordre aléatoire
  • • Pire cas : \(O(n \log n)\) - garanti
# Tri avec fonction personnalisée etudiants = [("Alice", 85), ("Bob", 92), ("Charlie", 78)] etudiants.sort(key=lambda x: x[1], reverse=True) # Tri par note décroissante # Résultat: [("Bob", 92), ("Alice", 85), ("Charlie", 78)]
4. Slicing et indexation avancée
✂️ Slicing (découpage)

Le slicing permet d'extraire des sous-séquences de manière efficace. La syntaxe générale est :

liste[début:fin:pas]

Où :

  • 🔹 début : index de départ (inclus)
  • 🔹 fin : index de fin (exclu)
  • 🔹 pas : intervalle entre les éléments
0 1 2 3 4 5 0 1 2 3 4 5 -6 -5 -4 -3 -2 -1 liste[2:4] Résultat: [2, 3] Indices 2 et 3 (fin exclue)
ma_liste = [0, 1, 2, 3, 4, 5] print(ma_liste[1:4]) # [1, 2, 3] print(ma_liste[:3]) # [0, 1, 2] (début omis) print(ma_liste[2:]) # [2, 3, 4, 5] (fin omise) print(ma_liste[::2]) # [0, 2, 4] (pas de 2) print(ma_liste[::-1]) # [5, 4, 3, 2, 1, 0] (inversé)
🧶 Listes imbriquées et matrices

Les listes imbriquées permettent de créer des structures de données multidimensionnelles. Elles sont particulièrement utiles pour représenter des matrices, des tableaux ou des structures hiérarchiques.

1 2 3 4 5 6 7 8 9 0 1 2 0 1 2 matrice[0][1] → 2 matrice[1][2] → 6 matrice[2][0] → 7 Accès: matrice[i][j] avec \(0 \leq i, j < n\)
# Création d'une matrice 3x3
matrice = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
# Création par compréhension
matrice_zeros = [[0 for _ in range(3)] for _ in range(3)]
# Parcours de matrice
for i in range(len(matrice)):
     for j in range(len(matrice[i])):
        print(f"matrice[{i}][{j}] = {matrice[i][j]}")
⚠️ Pièges courants avec les listes imbriquées :
# ERREUR : Toutes les lignes pointent vers la même liste matrice_erronee = [[0] * 3] * 3 matrice_erronee[0][0] = 1 # Modifie TOUTES les lignes ! # CORRECT : Chaque ligne est une liste distincte matrice_correcte = [[0] * 3 for _ in range(3)] matrice_correcte[0][0] = 1 # Modifie seulement la première ligne
5. Compréhensions de listes et techniques avancées
🎯 Compréhensions de listes

Les compréhensions de listes (list comprehensions) offrent une syntaxe concise et pythonique pour créer des listes. Elles sont généralement plus rapides que les boucles équivalentes.

Syntaxe générale :
[expression for item in iterable if condition]
1 2 3 4 Données originales x² pour x pair 4 16 Résultat filtré
# Exemples de compréhensions
carres = [x**2 for x in range(5)] # [0, 1, 4, 9, 16]
pairs = [x for x in range(10) if x % 2 == 0] # [0, 2, 4, 6, 8]
mots_majuscules = [mot.upper() for mot in ["python", "est", "génial"]] # ["PYTHON", "EST", "GÉNIAL"] # Compréhension avec condition
carres_pairs = [x**2 for x in range(10) if x % 2 == 0] # [0, 4, 16, 36, 64]
🏃‍♂️ Performances et optimisations

Les compréhensions de listes sont généralement plus rapides que les boucles traditionnelles car elles sont optimisées au niveau du bytecode Python.

Comparaison de performance :
✓ Rapide: [x**2 for x in range(1000)]
✗ Plus lent: Liste créée avec append() dans une boucle
Compréhension Map/Filter Boucle for Temps d'exécution relatif 1x 1.5x 2.5x
# Compréhensions imbriquées pour matrices
matrice = [[i*j for j in range(3)] for i in range(3)]
# [[0, 0, 0], [0, 1, 2], [0, 2, 4]]
# Aplatissement d'une matrice
matrice_aplatie = [x for ligne in matrice for x in ligne]
# [0, 0, 0, 0, 1, 2, 0, 2, 4]
# Filtre avec condition complexe
nombres = [x for x in range(100) if x % 3 == 0 and x % 5 == 0] # Multiples de 15: [0, 15, 30, 45, 60, 75, 90]
6. Gestion mémoire et bonnes pratiques
🧠 Gestion mémoire

Python gère automatiquement la mémoire pour les listes, mais il est important de comprendre les implications des différentes opérations :

Références vs Copies :
liste1 Mémoire: [1, 2, 3] liste2 liste2 = liste1 liste3 Mémoire: [1, 2, 3] liste3 = liste1.copy()
# Référence (même objet en mémoire)
liste1 = [1, 2, 3]
liste2 = liste1 # Référence
liste2.append(4) # Modifie aussi liste1
print(liste1) # [1, 2, 3, 4]
# Copie (nouvel objet)
liste3 = liste1.copy() # Copie superficielle
liste3.append(5) # N'affecte pas liste1
print(liste1) # [1, 2, 3, 4]
print(liste3) # [1, 2, 3, 4, 5]
📋 Bonnes pratiques

Adopter de bonnes pratiques permet d'écrire du code plus lisible, maintenable et performant :

✅ À faire :
  • 🔹 Utilisez les compréhensions pour les transformations simples
  • 🔹 Préférez copy() aux slices vides [:]
  • 🔹 Utilisez enumerate() pour les indices
  • 🔹 Employez zip() pour itérer sur plusieurs listes
❌ À éviter :
  • 🔹 Modifier une liste pendant l'itération
  • 🔹 Utiliser des slices pour copier des objets mutables
  • 🔹 Ignorer la gestion des exceptions
  • 🔹 Créer des variables globales inutiles
Listes en Python

Exercice 1: ★ ★ ☆ ☆ ☆

Étant donné la liste suivante : nombres = [10, 20, 30, 40, 50]
1. Ajoutez l'élément 60 à la fin de la liste
2. Modifiez le deuxième élément pour qu'il devienne 25
3. Affichez le dernier élément de la liste

       
# Solution :
nombres = [10, 20, 30, 40, 50]

# 1. Ajout en fin de liste
nombres.append(60)

# 2. Modification du 2ème élément (indice 1)
nombres[1] = 25

# 3. Affichage du dernier élément
print(nombres[-1])  # Affiche 60

# Liste finale : [10, 25, 30, 40, 50, 60]
   


Exercice 2: ★ ★ ★ ☆ ☆

Étant donné deux listes : liste1 = [1, 2, 3] et liste2 = ['a', 'b', 'c']
1. Concaténez-les pour obtenir [1, 2, 3, 'a', 'b', 'c']
2. Créez une liste imbriquée [[1, 'a'], [2, 'b'], [3, 'c']]
3. Extrayez 'b' de la liste résultante de la question 2

       
# Solution :
liste1 = [1, 2, 3]
liste2 = ['a', 'b', 'c']

# 1. Concaténation
liste_concat = liste1 + liste2  # [1, 2, 3, 'a', 'b', 'c']

# 2. Liste imbriquée
liste_imbriquee = [[liste1[i], liste2[i]] for i in range(len(liste1))]

# 3. Extraction de 'b'
element_b = liste_imbriquee[1][1]  # Récupère 'b'

# Variante pour la question 2 :
# liste_imbriquee = list(zip(liste1, liste2))
   


Exercice 3: ★ ★ ★ ★ ☆

Étant donné la liste : data = [12, 5, 8, 19, 3, 7]
1. Triez la liste par ordre croissant
2. Calculez la somme des éléments
3. Créez une nouvelle liste avec les carrés des éléments impairs
4. Trouvez l'indice de la valeur maximale

       
# Solution :
data = [12, 5, 8, 19, 3, 7]

# 1. Tri croissant
data.sort()  # [3, 5, 7, 8, 12, 19]

# 2. Somme des éléments
somme = sum(data)  # 54

# 3. Carrés des éléments impairs
carres_impairs = [x**2 for x in data if x % 2 != 0]  # [25, 49, 9]

# 4. Indice de la valeur maximale
indice_max = data.index(max(data))  # 5 (car trié, dernier élément)

# Variante non triée :
# indice_max = data.index(max(data))
   


Exercice 4: ★ ★ ★ ★ ★

Étant donné la liste : mix = [4, 'a', 7, 'b', 'c', 9, 2]
1. Séparez les nombres et les chaînes dans deux listes distinctes
2. Inversez l'ordre des éléments de la liste originale
3. Supprimez tous les éléments non numériques de la liste originale
4. Créez une liste des multiples de 3 à partir des nombres

       
# Solution :
mix = [4, 'a', 7, 'b', 'c', 9, 2]

# 1. Séparation
nombres = [x for x in mix if isinstance(x, int)]
chaines = [x for x in mix if isinstance(x, str)]

# 2. Inversion de l'ordre
mix.reverse()  # [2, 9, 'c', 'b', 7, 'a', 4]

# 3. Suppression des non-numériques
mix = [x for x in mix if isinstance(x, int)]  # [2, 9, 7, 4]

# 4. Multiples de 3
multiples_3 = [x for x in nombres if x % 3 == 0]  # [9]
   


Exercice 5: ★ ★ ★ ★ ★

Étant donné la matrice : matrice = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
1. Affichez l'élément central (5)
2. Calculez la somme de chaque ligne
3. Transposez la matrice (échanger lignes et colonnes)
4. Créez une liste avec les éléments de la diagonale principale

       
# Solution :
matrice = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]

# 1. Élément central
centre = matrice[1][1]  # 5

# 2. Somme de chaque ligne
sommes_lignes = [sum(ligne) for ligne in matrice]  # [6, 15, 24]

# 3. Transposition
matrice_transposee = [[ligne[i] for ligne in matrice] for i in range(3)]
# [[1, 4, 7], [2, 5, 8], [3, 6, 9]]

# 4. Diagonale principale
diagonale = [matrice[i][i] for i in range(3)]  # [1, 5, 9]

# Variante avec numpy pour la transposition :
# import numpy as np; np.array(matrice).T.tolist()
   


Listes et Fonctions en Python

Exercice 6: ★ ★ ★ ☆ ☆

Créez une fonction somme_liste qui : 1. Prend une liste de nombres en paramètre 2. Retourne la somme de ses éléments 3. Testez-la avec [1, 2, 3, 4, 5] (doit retourner 15)

       
def somme_liste(nombres):
    return sum(nombres)

# Test
print(somme_liste([1, 2, 3, 4, 5]))  # 15

# Version alternative sans sum():
def somme_liste_alt(nombres):
    total = 0
    for num in nombres:
        total += num
    return total
   


Exercice 7: ★ ★ ★ ☆ ☆

Créez une fonction filtrer_pairs qui : 1. Prend une liste de nombres en paramètre 2. Retourne une nouvelle liste contenant seulement les nombres pairs 3. Testez-la avec [1, 2, 3, 4, 5, 6, 7, 8] (doit retourner [2, 4, 6, 8])

       
def filtrer_pairs(nombres):
    return [x for x in nombres if x % 2 == 0]

# Test
print(filtrer_pairs([1, 2, 3, 4, 5, 6, 7, 8]))  # [2, 4, 6, 8]

# Version alternative avec boucle for:
def filtrer_pairs_alt(nombres):
    pairs = []
    for num in nombres:
        if num % 2 == 0:
            pairs.append(num)
    return pairs
   


Exercice 8: ★ ★ ★ ★ ☆

Créez une fonction moyenne_ponderee qui : 1. Prend deux listes (valeurs et poids) de même longueur 2. Retourne la moyenne pondérée des valeurs 3. Testez-la avec valeurs = [10, 20, 30] et poids = [1, 2, 3] (doit retourner 23.33)

       
def moyenne_ponderee(valeurs, poids):
    somme_produits = sum(v * p for v, p in zip(valeurs, poids))
    somme_poids = sum(poids)
    return round(somme_produits / somme_poids, 2)

# Test
print(moyenne_ponderee([10, 20, 30], [1, 2, 3]))  # 23.33

# Gestion d'erreur possible :
if len(valeurs) != len(poids):
    raise ValueError("Les listes doivent avoir la même longueur")
   


Exercice 9: ★ ★ ★ ★ ★

Créez une fonction matrice_carre qui : 1. Prend une liste de listes (matrice carrée) 2. Retourne True si c'est une matrice carrée (même nombre de lignes et colonnes), False sinon 3. Testez-la avec [[1, 2], [3, 4]] (True) et [[1, 2, 3], [4, 5]] (False)

       
def matrice_carre(matrice):
    n = len(matrice)
    return all(len(ligne) == n for ligne in matrice)

# Tests
print(matrice_carre([[1, 2], [3, 4]]))    # True
print(matrice_carre([[1, 2, 3], [4, 5]])) # False

# Version alternative :
def matrice_carre_alt(matrice):
    taille = len(matrice)
    for ligne in matrice:
        if len(ligne) != taille:
            return False
    return True
   


Exercice 10: ★ ★ ★ ★ ★

Créez une fonction fusion_triee qui : 1. Prend deux listes triées en entrée 2. Retourne une nouvelle liste triée contenant les éléments des deux listes 3. Testez-la avec [1, 3, 5] et [2, 4, 6] (doit retourner [1, 2, 3, 4, 5, 6]) 4. Bonus: Faites-le sans utiliser sort()

       
# Version simple avec sort()
def fusion_triee(liste1, liste2):
    fusion = liste1 + liste2
    fusion.sort()
    return fusion

# Version algorithmique (sans sort())
def fusion_triee_opti(liste1, liste2):
    resultat = []
    i = j = 0
    
    while i < len(liste1) and j < len(liste2):
        if liste1[i] < liste2[j]:
            resultat.append(liste1[i])
            i += 1
        else:
            resultat.append(liste2[j])
            j += 1
    
    # Ajouter les éléments restants
    resultat.extend(liste1[i:])
    resultat.extend(liste2[j:])
    
    return resultat

# Tests
print(fusion_triee([1, 3, 5], [2, 4, 6]))  # [1, 2, 3, 4, 5, 6]
print(fusion_triee_opti([1, 3, 5], [2, 4, 6]))  # [1, 2, 3, 4, 5, 6]
   


📝 Mémento des Listes Python
🔨 Création
# Liste vide
ma_liste = []
ma_liste = list()

# Avec éléments
nombres = [1, 2, 3, 4]
fruits = ['pomme', 'banane']
🎯 Accès
liste = ['a', 'b', 'c', 'd']
liste[0] # → 'a' (premier)
liste[-1] # → 'd' (dernier)
liste[1:3] # → ['b', 'c']
liste[:2] # → ['a', 'b']
liste[2:] # → ['c', 'd']
➕ Ajout
liste.append(element) # Fin
liste.insert(index, elem) # Position
liste1.extend(liste2) # Concaténer
liste + autre_liste # Nouvelle liste
🗑️ Suppression
liste.remove(element) # Par valeur
liste.pop() # Dernier
liste.pop(index) # Par index
del liste[index] # Par index
liste.clear() # Tout vider
🔍 Recherche & Tri
element in liste # Teste présence
liste.index(element) # Position
liste.count(element) # Occurrences
liste.sort() # Tri croissant
liste.reverse() # Inverse ordre
ℹ️ Informations
len(liste) # Taille
max(liste) # Maximum
min(liste) # Minimum
sum(liste) # Somme (nombres)
bool(liste) # True si non vide
🧪 Testeur Interactif
Ma Liste :
[ ]
Informations :
Taille: 0
Vide: Oui
💡 Astuces
• Les listes sont mutables (modifiables)
• Index négatifs comptent depuis la fin
• Slicing [start:end:step]
• Liste de listes = tableau 2D
• list(range(5)) → [0,1,2,3,4]
• Copie : nouvelle_liste = liste[:]

Forum(s) associé(s)

Page: