L'évaluation paresseuse (lazy evaluation) est un concept clé de la programmation efficace, où les valeurs ne sont calculées que si nécessaire. Historiquement, toutes les structures de base intégrées en Python (listes, tuples) étaient "affamées" : elles créent et placent en mémoire tous les éléments à l'avance. Avec l'augmentation des volumes de données et des tâches de traitement de flux, il est devenu nécessaire d'avoir des calculs paresseux.
Problème : les calculs affamés entraînent une utilisation inefficace de la mémoire et du temps là où des résultats peuvent être obtenus progressivement - par exemple, lors du filtrage, de la transformation de longues collections ou du streaming de fichiers.
Solution : Python a introduit de nombreux outils pour les calculs paresseux : générateurs, itérateurs, ainsi que des fonctions de la bibliothèque standard (map, filter, zip, enumerate) et le module itertools. Tous retournent non pas des collections prêtes, mais des objets "paresseux" qui produisent un résultat valeur par valeur.
Exemple de code :
result = map(lambda x: x * x, range(100)) # retournera un générateur itérateur for y in result: print(y) # les valeurs sont calculées au fur et à mesure de l'itération import itertools inf = itertools.count(1) for i in inf: if i > 3: break print(i) # 1, 2, 3
Caractéristiques clés :
Les fonctions map/filter retournent-elles toujours une liste en Python3 ?
Non, en Python 3, ces fonctions retournent des itérateurs, pas des listes. Pour obtenir une liste, il faut envelopper le résultat dans list().
x = map(int, ['1', '2']) # <objet map> list(x) # [1, 2]
Peut-on obtenir la longueur du résultat de map sans le convertir en liste ?
Non, un itérateur ne sait pas à l'avance combien d'éléments il contient, tant qu'il n'a pas parcouru tous les éléments. Il faut le calculer via list(), ce qui annule la paresse.
La fonction range en Python3 est-elle affamée ou paresseuse ?
Paresseuse : range crée un "objet range" — il "calcule" les éléments à la demande, sans stocker toute la séquence.
Un script traite un énorme fichier CSV en créant une liste de toutes les lignes via list(open(f)). Le serveur "meurt" à cause du manque de mémoire avec un grand fichier.
Avantages :
Inconvénients :
Le code utilise un traitement paresseux : il parcourt les lignes du fichier avec un itérateur for line in open(f), ou les traite via map/filter sans créer de collections intermédiaires.
Avantages :
Inconvénients :