Transformer chaque élément d’une liste sans écrire une boucle complète est l’un des besoins les plus fréquents en Python. La fonction map() permet d’appliquer la même opération à un ou plusieurs itérables, tout en produisant les résultats progressivement. Je vous montre son fonctionnement, ses usages concrets, ses limites et les situations où une compréhension de liste reste plus lisible.
L’essentiel à retenir sur map() en Python
- map() applique une fonction à chaque élément d’un itérable.
- Elle renvoie un itérateur paresseux, pas directement une liste.
- Il faut utiliser list() pour afficher ou stocker tous les résultats.
- Plusieurs itérables peuvent être traités en parallèle avec une fonction adaptée.
- Pour une logique complexe, la compréhension de liste est souvent plus claire.
Que fait réellement map() en Python
La syntaxe générale est simple : map(fonction, iterable). Python prend chaque valeur de l’itérable, l’envoie à la fonction indiquée, puis renvoie les résultats sous la forme d’un objet map.
nombres = [1, 2, 3, 4]
resultat = map(lambda x: x * 2, nombres)
print(list(resultat))
# [2, 4, 6, 8]
Le point qui surprend le plus souvent est que map() ne crée pas immédiatement une nouvelle liste. Elle renvoie un itérateur, c’est-à-dire un objet qui calcule les valeurs au moment où le programme les demande. C’est pratique pour limiter l’utilisation de la mémoire sur de grands volumes de données.
Sans conversion en liste, l’affichage reste peu parlant :
nombres = [1, 2, 3]
resultat = map(str, nombres)
print(resultat)
#
Pour parcourir les valeurs, deux solutions sont courantes. Je peux convertir l’objet en liste ou l’utiliser directement dans une boucle. La seconde méthode évite de conserver tous les résultats en mémoire.
nombres = [1, 2, 3]
for valeur in map(str, nombres):
print(valeur)
Un itérateur est généralement consommable une seule fois. Après un premier parcours, il ne reste plus de valeurs à lire. C’est une différence importante avec une liste, que l’on peut parcourir plusieurs fois.

Les usages les plus utiles au quotidien
Le cas le plus évident consiste à appliquer une transformation identique à toutes les valeurs. Pour convertir des nombres en nombres décimaux, par exemple, map() rend l’intention immédiatement visible.
valeurs = ["12.5", "8.75", "19.0"]
prix = list(map(float, valeurs))
print(prix)
# [12.5, 8.75, 19.0]
J’utilise aussi cette fonction pour nettoyer des chaînes de caractères. Ici, chaque élément est débarrassé des espaces inutiles grâce à la méthode strip().
noms = [" Alice ", "Bob ", " Claire"]
noms_propres = list(map(str.strip, noms))
print(noms_propres)
# ['Alice', 'Bob', 'Claire']
Cette écriture est plus concise qu’une boucle, mais elle reste lisible parce que la méthode appelée est explicite. Pour une opération très courte, une fonction lambda convient également.
temperatures = [18, 21, 25, 17]
fahrenheit = list(map(lambda c: c * 9 / 5 + 32, temperatures))
print(fahrenheit)
# [64.4, 69.8, 77.0, 62.6]
Personnellement, je réserve lambda aux transformations simples. Dès que l’expression devient longue ou contient plusieurs conditions, je préfère définir une fonction séparée. Le code devient plus facile à tester et le nom de la fonction explique mieux son rôle.
def convertir_en_fahrenheit(celsius):
return celsius * 9 / 5 + 32
temperatures = [18, 21, 25, 17]
resultat = list(map(convertir_en_fahrenheit, temperatures))
On peut également utiliser une fonction déjà intégrée à Python, comme abs(), len(), round() ou str.lower. Cette approche évite souvent d’écrire une fonction artificielle uniquement pour alimenter map().
Traiter plusieurs listes en parallèle
La fonction accepte plusieurs itérables. Dans ce cas, la fonction appliquée doit recevoir autant d’arguments qu’il y a d’itérables. C’est utile pour additionner deux séries de nombres ou comparer des valeurs correspondantes.
prix = [10, 20, 30]
quantites = [2, 1, 4]
totaux = list(map(lambda p, q: p * q, prix, quantites))
print(totaux)
# [20, 20, 120]
Python associe le premier élément de la première liste au premier élément de la seconde, puis continue dans le même ordre. Avec trois listes, la fonction devra donc recevoir trois paramètres.
prenoms = ["Alice", "Benoît", "Chloé"]
villes = ["Paris", "Lyon", "Lille"]
etiquettes = list(map(lambda nom, ville: f"{nom} - {ville}",
prenoms, villes))
print(etiquettes)
# ['Alice - Paris', 'Benoît - Lyon', 'Chloé - Lille']
Lorsque les longueurs diffèrent, l’itération s’arrête dès que l’itérable le plus court est épuisé. Les éléments restants des listes plus longues sont donc ignorés.
a = [1, 2, 3, 4]
b = [10, 20]
resultat = list(map(lambda x, y: x + y, a, b))
print(resultat)
# [11, 22]
C’est un comportement pratique si les données sont déjà alignées et que l’on veut éviter une erreur. En revanche, il peut masquer un problème de qualité des données. Lorsque toutes les valeurs doivent absolument être présentes, je vérifie d’abord les longueurs ou j’utilise zip() avec une validation explicite.
map() ou compréhension de liste
Dans Python moderne, map() n’est pas toujours la solution la plus lisible. Une compréhension de liste exprime souvent plus naturellement une transformation, surtout lorsqu’il faut ajouter une condition.
| Situation | Approche conseillée | Pourquoi |
|---|---|---|
| Appliquer une fonction existante | map() |
Syntaxe courte et directe |
| Transformation simple avec une expression | Compréhension de liste | Lecture souvent plus naturelle |
| Ajouter une condition | Compréhension de liste | Le filtrage est intégré |
| Effectuer plusieurs étapes | Boucle classique ou fonction dédiée | Logique plus facile à maintenir |
Ces deux écritures produisent le même résultat :
nombres = [1, 2, 3, 4]
avec_map = list(map(lambda x: x * x, nombres))
avec_comprehension = [x * x for x in nombres]
Pour moi, la compréhension de liste gagne dès qu’elle permet de lire la transformation comme une phrase. Elle devient particulièrement intéressante avec un filtre.
nombres = [1, 2, 3, 4, 5, 6]
pairs = [x * 2 for x in nombres if x % 2 == 0]
print(pairs)
# [4, 8, 12]
Avec map(), il faudrait généralement combiner map() et filter(), ce qui ajoute une couche de lecture. À l’inverse, lorsque je veux appliquer directement une fonction connue comme int ou str.strip, map() est souvent plus élégante que de créer une compréhension uniquement pour cette opération.
Les erreurs fréquentes et les limites à connaître
Oublier que map() est paresseuse
L’erreur la plus courante consiste à croire que la fonction a déjà calculé tous les résultats. Tant que l’itérateur n’est pas parcouru, la transformation n’est pas exécutée. Cela explique pourquoi une exception peut apparaître au moment de la boucle plutôt qu’à la ligne où map() est appelée.
valeurs = ["10", "abc", "30"]
resultat = map(int, valeurs)
print(list(resultat))
# ValueError à cause de "abc"
Réutiliser un itérateur déjà consommé
Après une conversion en liste, l’objet map initial est vide. Si les résultats doivent être consultés plusieurs fois, je stocke la liste obtenue dans une variable plutôt que l’itérateur lui-même.
resultat = map(str.upper, ["a", "b"])
premiere_lecture = list(resultat)
seconde_lecture = list(resultat)
print(premiere_lecture)
# ['A', 'B']
print(seconde_lecture)
# []
Lire aussi : Tkinter Frame - Structurez vos interfaces Python proprement
Utiliser map() pour des effets de bord
Une transformation est le meilleur terrain pour map(). En revanche, l’utiliser uniquement pour appeler print(), modifier une variable externe ou enregistrer des données rend souvent le code confus. Dans ce cas, une boucle for décrit plus honnêtement ce que le programme fait.
noms = ["Alice", "Bob"]
for nom in noms:
print(f"Bonjour {nom}")
La fonction n’est pas automatiquement plus rapide dans toutes les situations. Elle peut réduire les allocations grâce à son fonctionnement paresseux, mais la lisibilité, la nature de la fonction appelée et le volume de données comptent davantage que quelques micro-optimisations. Je mesure donc les performances uniquement lorsque le programme traite réellement beaucoup de données.
Une méthode simple pour bien choisir
Je prends généralement trois décisions avant d’utiliser map(). Si une fonction existante doit être appliquée à chaque élément, c’est un bon candidat. Si la logique contient une condition ou plusieurs opérations, une compréhension de liste ou une fonction dédiée sera souvent préférable.
- Choisissez
map()pour une transformation uniforme et facile à nommer. - Choisissez une compréhension de liste si vous avez besoin d’un filtre.
- Choisissez une boucle si le traitement comporte plusieurs étapes ou des effets de bord.
- Convertissez en liste uniquement lorsque vous avez besoin de stocker ou d’afficher toutes les valeurs.
- Vérifiez les longueurs lorsque plusieurs itérables sont traités ensemble.
Le meilleur code n’est donc pas celui qui évite absolument les boucles. C’est celui dont l’intention se comprend rapidement. Dans un petit script, la différence est minime, mais dans une application de données, un code lisible évite bien plus d’erreurs qu’une écriture artificiellement compacte.
Ce que map() apporte vraiment dans un projet Python
map() est une fonction simple, mais elle introduit une idée importante de Python : séparer l’opération des données. On indique quelle transformation effectuer, puis on laisse l’itérateur parcourir les valeurs au moment opportun.
Retenez surtout trois points. La fonction renvoie un itérateur, elle peut travailler sur plusieurs sources et elle n’est pertinente que si elle rend le code plus clair. Pour une transformation directe, elle est efficace et élégante. Pour une logique conditionnelle ou complexe, une compréhension de liste ou une boucle bien nommée sera souvent un meilleur choix.
Avec cette règle simple, vous éviterez les deux excès les plus courants : ignorer complètement map() alors qu’elle simplifie le code, ou l’utiliser partout au détriment de la lisibilité.