Cette fiche rassemble des astuces pratiques et des techniques avancées pour améliorer votre code Python, optimiser vos scripts, et utiliser le langage de manière plus efficace au quotidien.
📑 Sommaire
🪄 L'opérateur "walrus" (:=)
Introduit avec Python 3.8, cet opérateur permet de réaliser une affectation dans une expression :
# Sans opérateur walrus
texte = input("Entrez un texte : ")
if len(texte) > 0:
print(f"Vous avez saisi {len(texte)} caractères")
# Avec opérateur walrus
if (n := len(input("Entrez un texte : "))) > 0:
print(f"Vous avez saisi {n} caractères")
Très utile dans les conditions, les boucles while et les compréhensions :
# Traiter des lignes jusqu'à une ligne vide
while (ligne := input()) != "":
print(f"Traitement de : {ligne}")
# Filtrer des résultats avec une condition complexe
resultats = [resultat for x in data if (resultat := f(x)) > 0]
🚀 Compréhensions avancées
Les compréhensions permettent d'écrire du code concis et expressif :
# Compréhension de liste avec conditions
nombres = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
cubes_pairs = [x**3 for x in nombres if x % 2 == 0]
print(cubes_pairs) # [8, 64, 216, 512, 1000]
# Compréhension imbriquée (matrice 3x3)
matrice = [[i*3+j+1 for j in range(3)] for i in range(3)]
print(matrice) # [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
# Compréhension de dictionnaire avec condition
carre_pairs = {x: x**2 for x in range(10) if x % 2 == 0}
print(carre_pairs) # {0: 0, 2: 4, 4: 16, 6: 36, 8: 64}
# Compréhension d'ensemble avec transformation
voyelles = {lettre.upper() for lettre in "bonjour" if lettre in "aeiouy"}
print(voyelles) # {'O', 'U'}
⚙️ Déballage multiple
Le déballage (unpacking) permet d'extraire des valeurs de séquences de manière élégante :
# Déballage simple
a, b, c = [1, 2, 3]
print(a, b, c) # 1 2 3
# Ignorer certaines valeurs avec _
a, _, c = [1, 2, 3]
print(a, c) # 1 3
# Déballage avec * (reste dans une liste)
premier, *milieu, dernier = [1, 2, 3, 4, 5]
print(premier) # 1
print(milieu) # [2, 3, 4]
print(dernier) # 5
# Échanger des valeurs sans variable temporaire
a, b = 10, 20
a, b = b, a
print(a, b) # 20 10
# Déballage de dictionnaire avec **
def afficher_infos(nom, age, ville):
print(f"{nom}, {age} ans, habite à {ville}")
personne = {"nom": "Alice", "age": 30, "ville": "Paris"}
afficher_infos(**personne) # Alice, 30 ans, habite à Paris
🪤 Gestion fine des exceptions
Capturez et gérez précisément les différents types d'erreurs :
# Capture multiple d'exceptions
try:
valeur = int(input("Entrez un nombre : "))
resultat = 10 / valeur
print(f"Résultat : {resultat}")
except ValueError:
print("Ceci n'est pas un nombre valide")
except ZeroDivisionError:
print("Division par zéro impossible")
except Exception as e:
print(f"Erreur inattendue : {e}")
else:
print("Aucune erreur n'est survenue")
finally:
print("Cette partie s'exécute toujours")
Grouper plusieurs exceptions :
try:
# Code susceptible de générer des erreurs
pass
except (ValueError, TypeError) as e:
print(f"Erreur de type : {e}")
⏱️ Mesurer la performance
Plusieurs façons de mesurer le temps d'exécution de votre code :
# Méthode simple avec time
import time
start = time.time()
# ... votre code ...
end = time.time()
print(f"Durée : {end - start:.4f} secondes")
Utilisation de timeit pour des mesures précises :
import timeit
# Mesurer une ligne
temps = timeit.timeit('[x**2 for x in range(1000)]', number=10000)
print(f"Temps d'exécution : {temps:.4f} secondes")
# Mesurer une fonction
def ma_fonction():
return sum(x**2 for x in range(1000))
temps = timeit.timeit(ma_fonction, number=10000)
print(f"Temps d'exécution : {temps:.4f} secondes")
Décorateur pour profiler une fonction :
def chronometre(func):
def wrapper(*args, **kwargs):
start = time.time()
result = func(*args, **kwargs)
end = time.time()
print(f"{func.__name__} a pris {end - start:.4f} secondes")
return result
return wrapper
@chronometre
def operation_couteuse():
time.sleep(1) # Simuler une opération longue
return "Terminé"
operation_couteuse() # Affiche : operation_couteuse a pris 1.0012 secondes
🎁 Bonus : Astuces avancées
Chaînes f (f-strings) avec formatage avancé
# Format avec la spécification de précision
nombre = 123.456789
print(f"{nombre:.2f}") # 123.46
# Alignement et remplissage
for i in range(1, 11):
print(f"{i:03d} - {i*i:4d} - {i*i*i:5d}")
# Formatage de dates
from datetime import datetime
maintenant = datetime.now()
print(f"{maintenant:%d/%m/%Y %H:%M}") # Ex: 27/04/2025 14:30
# Débogage facile
x = 10
y = 20
print(f"{x=}, {y=}, {x+y=}") # x=10, y=20, x+y=30
Collections spécialisées
from collections import Counter, defaultdict, namedtuple
# Counter pour compter les occurrences
texte = "abracadabra"
compteur = Counter(texte)
print(compteur) # Counter({'a': 5, 'b': 2, 'r': 2, 'c': 1, 'd': 1})
print(compteur.most_common(2)) # [('a', 5), ('b', 2)]
# defaultdict pour des valeurs par défaut
fruits_par_couleur = defaultdict(list)
fruits_par_couleur["rouge"].append("pomme") # Pas d'erreur même si la clé n'existe pas
fruits_par_couleur["rouge"].append("fraise")
print(fruits_par_couleur) # defaultdict(, {'rouge': ['pomme', 'fraise']})
# namedtuple pour des tuples avec noms de champs
Point = namedtuple('Point', ['x', 'y'])
p = Point(10, 20)
print(p.x, p.y) # 10 20
print(p) # Point(x=10, y=20)
Trucs pour le débogage
# Utiliser pdb, le débogueur intégré
import pdb
def fonction_complexe(x):
y = x * 2
pdb.set_trace() # Le programme s'arrête ici et entre en mode débogage
z = y * 3
return z
# Utiliser `breakpoint()` (Python 3.7+) à la place de pdb.set_trace()
def autre_fonction(x):
y = x * 2
breakpoint() # Équivalent à pdb.set_trace()
z = y * 3
return z