EXAMEN python :
Exercice 1 : Détection de sous-listes strictement croissantes
Énoncé :
On considère une liste d'entiers. Écrire un programme Python qui vérifie si la liste contient au moins une sous-liste consécutive strictement croissante de longueur ≥ 3, retourne cette sous-liste si elle existe, sinon retourne une liste vide.
Solution :
Raisonnement : Nous devons parcourir la liste et détecter la première séquence d'au moins 3 nombres où chacun est strictement plus grand que le précédent.
Étape 1 : Parcourir la liste
On parcourt la liste jusqu'à l'avant-dernier triplet possible, c'est-à-dire jusqu'à l'indice len(liste)-3.
Étape 2 : Vérifier chaque triplet
Pour chaque position i, on vérifie si liste[i] < liste[i+1] < liste[i+2].
Étape 3 : Étendre la séquence trouvée
Quand on trouve un triplet croissant, on continue tant que l'élément suivant est plus grand que le précédent.
Code :
def sous_liste_croissante(liste):
"""
Cherche une sous-liste strictement croissante de longueur ≥ 3
"""
# Parcourir jusqu'à l'avant-dernier triplet possible
for i in range(len(liste) - 2):
# Vérifie si 3 éléments consécutifs sont strictement croissants
if liste[i] < liste[i+1] < liste[i+2]:
# On a trouvé un début de séquence
fin = i + 2
# Étendre la séquence tant que c'est croissant
while fin + 1 < len(liste) and liste[fin] < liste[fin+1]:
fin += 1
# Retourner la sous-liste trouvée
return liste[i:fin+1]
# Aucune séquence trouvée
return []
# Tests
print(sous_liste_croissante([1, 2, 3, 2, 4, 5, 6, 7])) # [1, 2, 3]
print(sous_liste_croissante([5, 4, 3, 2, 1])) # []
print(sous_liste_croissante([1, 2, 3, 4, 5])) # [1, 2, 3, 4, 5]
Exemple pas à pas avec [1, 3, 2, 4, 5, 6] :
- i=0 : 1 < 3 < 2 ? Non
- i=1 : 3 < 2 < 4 ? Non
- i=2 : 2 < 4 < 5 ? Oui → on étend : 5 < 6 ? Oui → fin=5
- Résultat : liste[2:6] = [2, 4, 5, 6]
Exercice 2 : Transformation conditionnelle d'une liste
Énoncé :
On considère une liste d'entiers. Écrire un programme qui remplace chaque nombre pair par son carré; remplace chaque nombre impair par son cube; retourne la nouvelle liste, sans modifier la liste initiale.
Solution :
Raisonnement : On crée une nouvelle liste et on applique une transformation selon la parité.
Code :
def transformer_liste(liste):
"""
Crée une nouvelle liste avec carrés pour pairs, cubes pour impairs
"""
nouvelle_liste = []
for nombre in liste:
if nombre % 2 == 0: # Pair
nouvelle_liste.append(nombre ** 2)
else: # Impair
nouvelle_liste.append(nombre ** 3)
return nouvelle_liste
# Version avec compréhension de liste
def transformer_liste_v2(liste):
return [x**2 if x % 2 == 0 else x**3 for x in liste]
# Test
print(transformer_liste([1, 2, 3, 4, 5])) # [1, 4, 27, 16, 125]
Explication pas à pas pour [1, 2, 3] :
- 1 est impair → 1³ = 1
- 2 est pair → 2² = 4
- 3 est impair → 3³ = 27
- Résultat : [1, 4, 27]
Exercice 3 : Regroupement par parité
Énoncé :
On considère une liste d'entiers. Écrire un programme qui crée un dictionnaire avec deux clés : "pairs" et "impairs", classe chaque élément de la liste dans la bonne catégorie, et retourne le dictionnaire.
Solution :
Code :
def regrouper_parite(liste):
"""
Retourne un dictionnaire avec les nombres pairs et impairs séparés
"""
resultat = {"pairs": [], "impairs": []}
for nombre in liste:
if nombre % 2 == 0:
resultat["pairs"].append(nombre)
else:
resultat["impairs"].append(nombre)
return resultat
# Test
print(regrouper_parite([1, 2, 3, 4, 5, 6]))
# {'pairs': [2, 4, 6], 'impairs': [1, 3, 5]}
Explication :
- On initialise un dictionnaire avec deux listes vides
- Pour chaque nombre, on teste sa parité avec % 2
- On ajoute à la liste correspondante
Exercice 4 : Détection d'un plateau maximal
Énoncé :
On considère une liste d'entiers. Un plateau est une suite d'éléments identiques consécutifs. Écrire un programme qui trouve le plateau le plus long, retourne un tuple (valeur, longueur) correspondant au plateau maximal.
Solution:
Code :
def plateau_maximal(liste):
"""
Trouve la plus longue séquence d'éléments identiques consécutifs
"""
if not liste:
return (None, 0)
plateau_actuel = liste[0]
longueur_actuelle = 1
plateau_max = plateau_actuel
longueur_max = 1
for i in range(1, len(liste)):
if liste[i] == liste[i-1]: # Même élément que précédent
longueur_actuelle += 1
if longueur_actuelle > longueur_max:
longueur_max = longueur_actuelle
plateau_max = liste[i]
else: # Changement d'élément
plateau_actuel = liste[i]
longueur_actuelle = 1
return (plateau_max, longueur_max)
# Test
print(plateau_maximal([1, 1, 2, 2, 2, 3, 3, 3, 3])) # (3, 4)
Explication pas à pas pour [1,1,2,2,2,3,3,3,3] :
- Début : plateau=1, long=1, max=1, max_long=1
- i=1: 1==1 → long=2, nouveau max (1,2)
- i=2: 2≠1 → nouveau plateau=2, long=1
- i=3: 2==2 → long=2
- i=4: 2==2 → long=3, nouveau max (2,3)
- i=5: 3≠2 → nouveau plateau=3, long=1
- i=6: 3==3 → long=2
- i=7: 3==3 → long=3
- i=8: 3==3 → long=4, nouveau max (3,4)
- Résultat : (3, 4)
Exercice 5 : Fonction d'analyse d'une liste
Énoncé :
On considère une liste d'entiers. Écrire une fonction analyse(liste) qui retourne la somme des éléments, retourne la moyenne, retourne le nombre d'éléments strictement supérieurs à la moyenne. La fonction doit retourner un tuple.
Solution détaillée :
Code :
def analyse(liste):
"""
Calcule somme, moyenne et nombre d'éléments supérieurs à la moyenne
"""
if not liste:
return (0, 0, 0)
somme = sum(liste)
moyenne = somme / len(liste)
# Compte les éléments > moyenne
superieurs = 0
for x in liste:
if x > moyenne:
superieurs += 1
return (somme, moyenne, superieurs)
# Version avec compréhension
def analyse_v2(liste):
if not liste:
return (0, 0, 0)
somme = sum(liste)
moyenne = somme / len(liste)
superieurs = sum(1 for x in liste if x > moyenne)
return (somme, moyenne, superieurs)
# Test
print(analyse([1, 2, 3, 4, 5])) # (15, 3.0, 2)
Explication pour [1,2,3,4,5] :
- Somme = 1+2+3+4+5 = 15
- Moyenne = 15/5 = 3.0
- Éléments > 3.0 : 4 et 5 → 2 éléments
- Résultat : (15, 3.0, 2)
Exercice 6 : Filtrage + transformation (lambda + map + filter)
Énoncé :
On considère une liste d'entiers. Écrire un programme Python qui : utilise une fonction lambda avec "filter()" pour extraire les nombres strictement positifs ; utilise une fonction lambda avec "map()" pour transformer chaque nombre extrait en son carré ; affiche la liste obtenue.
Solution détaillée :
Code :
def traiter_positifs(liste):
"""
Extrait les positifs et les transforme en carrés
"""
# Filtre les nombres positifs (> 0)
positifs = list(filter(lambda x: x > 0, liste))
# Transforme chaque positif en son carré
carres = list(map(lambda x: x**2, positifs))
return carres
# Version plus concise
def traiter_positifs_v2(liste):
return list(map(lambda x: x**2, filter(lambda x: x > 0, liste)))
# Test
print(traiter_positifs([-2, 3, -1, 4, 0, 5])) # [9, 16, 25]
Explication :
- filter(lambda x: x > 0, liste) garde seulement les éléments > 0
- map(lambda x: x**2, positifs) applique le carré à chaque élément
- list() convertit en liste car filter et map retournent des itérateurs
Exercice 7 : Sélection et agrégation (lambda + max)
Énoncé :
On considère une chaîne de caractères. Écrire un programme Python qui construit un dictionnaire {caractère : fréquence} en utilisant une fonction lambda pour déterminer le caractère le plus fréquent et affiche ce caractère et sa fréquence.
Solution détaillée :
Code :
def caractere_frequent(chaine):
"""
Trouve le caractère le plus fréquent dans une chaîne
"""
if not chaine:
return (None, 0)
# Compte les fréquences
frequences = {}
for c in chaine:
if c in frequences:
frequences[c] += 1
else:
frequences[c] = 1
# Trouve le max avec lambda sur les valeurs
plus_frequent = max(frequences.items(), key=lambda x: x[1])
return plus_frequent
# Version avec get()
def caractere_frequent_v2(chaine):
if not chaine:
return (None, 0)
frequences = {}
for c in chaine:
frequences[c] = frequences.get(c, 0) + 1
plus_frequent = max(frequences.items(), key=lambda x: x[1])
return plus_frequent
# Test
print(caractere_frequent("abracadabra")) # ('a', 5)
Explication pour "abracadabra" :
- Comptage : a:5, b:2, r:2, c:1, d:1
- max(..., key=lambda x: x[1]) cherche l'élément avec la plus grande valeur (fréquence)
- Résultat : ('a', 5)
Exercice 8 : Analyse des ventes d'un magasin
Énoncé :
Un magasin enregistre ses ventes sous la forme d'une liste de tuples :
ventes = [
("Laptop", [1200, 1350, 1280]),
("Phone", [800, 820, 780]),
("Tablet", [450, 470, 500]),
("Monitor", [300, 320, 310]),
("Printer", [200, 190, 210])
]
Solution détaillée :
Code :
ventes = [
("Laptop", [1200, 1350, 1280]),
("Phone", [800, 820, 780]),
("Tablet", [450, 470, 500]),
("Monitor", [300, 320, 310]),
("Printer", [200, 190, 210])
]
# 1. Afficher chaque produit suivi de son prix moyen
print("1. Prix moyens :")
moyennes = []
for produit, prix in ventes:
moyenne = sum(prix) / len(prix)
print(f"{produit}: {moyenne:.2f}")
moyennes.append((produit, moyenne))
print()
# 2. Produits avec prix moyen > 500
produits_chers = []
for produit, moyenne in moyennes:
if moyenne > 500:
produits_chers.append((produit, moyenne))
print("2. Produits avec moyenne > 500:", produits_chers)
print()
# 3. Produit avec prix moyen le plus élevé (sans max())
produit_max = moyennes[0]
for produit, moyenne in moyennes[1:]:
if moyenne > produit_max[1]:
produit_max = (produit, moyenne)
print("3. Produit avec moyenne max:", produit_max)
print()
# 4. Trier par prix moyen décroissant
def trier_moyenne_desc(liste_moyennes):
resultat = liste_moyennes.copy()
for i in range(len(resultat)):
for j in range(i+1, len(resultat)):
if resultat[i][1] < resultat[j][1]:
resultat[i], resultat[j] = resultat[j], resultat[i]
return resultat
print("4. Tri décroissant:", trier_moyenne_desc(moyennes))
print()
# 5. Produits > moyenne globale
tous_prix = []
for produit, prix in ventes:
tous_prix.extend(prix)
moyenne_globale = sum(tous_prix) / len(tous_prix)
produits_sup = []
for produit, moyenne in moyennes:
if moyenne > moyenne_globale:
produits_sup.append((produit, moyenne))
print("5. Produits > moyenne globale:", tuple(produits_sup))
Exercice 9 : Gestion d'inventaire
Énoncé :
stock = [
("Clavier", 15, 25),
("Souris", 8, 12),
("Ecran", 20, 7),
("Imprimante", 5, 30),
("Routeur", 12, 18)
]
Solution détaillée :
Code :
stock = [
("Clavier", 15, 25),
("Souris", 8, 12),
("Ecran", 20, 7),
("Imprimante", 5, 30),
("Routeur", 12, 18)
]
# 1. Produits en rupture imminente
print("1. Rupture imminente:")
ruptures = []
for nom, quantite, seuil in stock:
if quantite < seuil:
print(f"{nom}: {quantite} < {seuil}")
ruptures.append(nom)
print()
# 2. Produits sécurisés (quantité ≥ 2 × seuil)
securises = []
for nom, quantite, seuil in stock:
if quantite >= 2 * seuil:
securises.append(nom)
print("2. Produits sécurisés:", securises)
print()
# 3. Écart total de stock
ecarts = []
for nom, quantite, seuil in stock:
ecart = quantite - seuil
ecarts.append((nom, ecart))
print("3. Écarts:", ecarts)
print()
# 4. Écart le plus critique (le plus négatif)
critique = ecarts[0]
for nom, ecart in ecarts[1:]:
if ecart < critique[1]:
critique = (nom, ecart)
print("4. Écart le plus critique:", critique)
print()
# 5. Écart strictement positif et pair
positifs_pairs = []
for nom, ecart in ecarts:
if ecart > 0 and ecart % 2 == 0:
positifs_pairs.append((nom, ecart))
print("5. Écarts positifs et pairs:", tuple(positifs_pairs))
Exercice 10 : Planification de livraisons
Énoncé :
livraisons = [
("Camion_A", 120, 3),
("Camion_B", 80, 5),
("Camion_C", 150, 2),
("Camion_D", 60, 4)
]
Solution détaillée :
Code :
livraisons = [
("Camion_A", 120, 3),
("Camion_B", 80, 5),
("Camion_C", 150, 2),
("Camion_D", 60, 4)
]
# 1. Distance moyenne par livraison
print("1. Distances moyennes:")
moyennes = []
for nom, distance, nb in livraisons:
moyenne = distance / nb
print(f"{nom}: {moyenne:.2f} km/livraison")
moyennes.append((nom, moyenne))
print()
# 2. Camions avec > 100 km total
print("2. Camions > 100km:")
for nom, distance, _ in livraisons:
if distance > 100:
print(nom)
print()
# 3. Meilleur rendement (sans max())
meilleur = moyennes[0]
for nom, rend in moyennes[1:]:
if rend > meilleur[1]:
meilleur = (nom, rend)
print("3. Meilleur rendement:", meilleur)
print()
# 4. Tri par nombre de livraisons croissant
def trier_par_livraisons(data):
resultat = list(data)
for i in range(len(resultat)):
for j in range(i+1, len(resultat)):
if resultat[i][2] > resultat[j][2]:
resultat[i], resultat[j] = resultat[j], resultat[i]
return resultat
print("4. Tri par livraisons:", trier_par_livraisons(livraisons))
print()
# 5. Distance totale multiple de 3
multiples_3 = []
for nom, distance, _ in livraisons:
if distance % 3 == 0:
multiples_3.append(nom)
print("5. Distances multiples de 3:", tuple(multiples_3))
Exercice 11 : Analyse d'événements système
Énoncé :
logs = [("INFO", 120), ("ERROR", 15), ("WARNING", 40), ("CRITICAL", 5), ("DEBUG", 200)]
Solution détaillée :
Code :
logs = [("INFO", 120), ("ERROR", 15), ("WARNING", 40), ("CRITICAL", 5), ("DEBUG", 200)]
# 1. Nombre total d'événements
total = 0
for _, occ in logs:
total += occ
print("1. Total événements:", total)
print()
# 2. Types > 10% du total
seuil = total * 0.1
print("2. Types > 10%:")
frequents = []
for type_evenement, occ in logs:
if occ > seuil:
print(f"{type_evenement}: {occ}")
frequents.append(type_evenement)
print()
# 3. Type le moins fréquent (sans min())
moins_frequent = logs[0]
for log in logs[1:]:
if log[1] < moins_frequent[1]:
moins_frequent = log
print("3. Type moins fréquent:", moins_frequent)
print()
# 4. Tri par fréquence décroissante
def trier_frequence_desc(data):
resultat = list(data)
for i in range(len(resultat)):
for j in range(i+1, len(resultat)):
if resultat[i][1] < resultat[j][1]:
resultat[i], resultat[j] = resultat[j], resultat[i]
return resultat
print("4. Tri décroissant:", trier_frequence_desc(logs))
print()
# 5. Types avec occurrences paires
pairs = []
for type_evenement, occ in logs:
if occ % 2 == 0:
pairs.append(type_evenement)
print("5. Types avec occurrences paires:", tuple(pairs))
Exercice 12 : Analyse de segments numériques
Énoncé :
segments = [(1, 5), (3, 8), (10, 15), (14, 18), (20, 25)]
Solution détaillée :
Code :
segments = [(1, 5), (3, 8), (10, 15), (14, 18), (20, 25)]
# 1. Longueur de chaque segment
print("1. Longueurs:")
longueurs = []
for debut, fin in segments:
longueur = fin - debut
longueurs.append((debut, fin, longueur))
print(f"({debut}, {fin}) -> {longueur}")
print()
# 2. Segments de longueur > 4
longs = []
for debut, fin in segments:
if fin - debut > 4:
longs.append((debut, fin))
print("2. Longueurs > 4:", longs)
print()
# 3. Segment le plus long (sans max())
longueurs_calc = [(debut, fin, fin-debut) for debut, fin in segments]
plus_long = longueurs_calc[0]
for s in longueurs_calc[1:]:
if s[2] > plus_long[2]:
plus_long = s
print("3. Segment le plus long:", (plus_long[0], plus_long[1]))
print()
# 4. Tri par longueur croissante
def trier_par_longueur(data):
resultat = [(d, f, f-d) for d, f in data]
for i in range(len(resultat)):
for j in range(i+1, len(resultat)):
if resultat[i][2] > resultat[j][2]:
resultat[i], resultat[j] = resultat[j], resultat[i]
return [(d, f) for d, f, _ in resultat]
print("4. Tri par longueur:", trier_par_longueur(segments))
print()
# 5. Segments de longueur paire
pairs = []
for debut, fin in segments:
if (fin - debut) % 2 == 0:
pairs.append((debut, fin))
print("5. Longueurs paires:", tuple(pairs))