Définition de la fonction map() en Python
La fonction map() est une fonction native de Python (built-in) qui permet d'appliquer une fonction à chaque élément d'un ou plusieurs itérables (comme une list, un tuple ou un sets). Elle retourne un objet map, qui est lui-même un itérable paresseux (lazy iterator), c'est-à-dire qu'il ne calcule les résultats que lorsqu'on les demande.
Si vous suivez notre formation complète sur Python, vous découvrirez que map() fait partie des fonctions fondamentales de la programmation fonctionnelle en Python, aux côtés de filter() et reduce(). Comprendre map() vous permettra d'écrire du code plus concis, plus lisible et souvent plus performant.
La fonction map() ne modifie jamais l'itérable d'origine. Elle crée un nouvel objet contenant les résultats de la transformation appliquée à chaque élément.
Syntaxe de map()
La syntaxe de la fonction map() est très simple :
map(fonction, iterable, ...)Elle prend au minimum deux arguments :
- fonction : la fonction à appliquer à chaque élément. Il peut s'agir d'une fonction classique définie avec def, d'une fonction lambda, ou de toute autre callable.
- iterable : un ou plusieurs itérables dont les éléments seront passés à la fonction.
La valeur de retour est un objet map que vous pouvez convertir en list, tuple ou tout autre type de collection.
# Syntaxe de base
resultat = map(fonction, iterable)
# Avec plusieurs itérables
resultat = map(fonction, iterable1, iterable2)
# Conversion en liste pour voir les résultats
liste_resultat = list(map(fonction, iterable))Exemples pratiques de map()
Exemple 1 : Appliquer une fonction simple
L'utilisation la plus courante de map() consiste à appliquer une transformation à chaque élément d'une liste. Commençons par un exemple simple : mettre au carré chaque nombre d'une liste.
# Définir une fonction de transformation
def carre(x):
return x ** 2
# Liste de nombres
nombres = [1, 2, 3, 4, 5]
# Appliquer map()
resultat = map(carre, nombres)
# Convertir en liste pour afficher
print(list(resultat)) # [1, 4, 9, 16, 25]Ici, la fonction carre() est appliquée à chaque élément de la liste nombres. Le résultat est un nouvel objet contenant les valeurs transformées.
Exemple 2 : Utiliser map() avec une fonction lambda
Pour des transformations simples, il est courant d'utiliser une fonction lambda directement dans map(). Cela évite de définir une fonction séparée pour une opération triviale.
# Convertir des températures de Celsius en Fahrenheit
celsius = [0, 20, 37, 100]
fahrenheit = list(map(lambda c: c * 9/5 + 32, celsius))
print(fahrenheit) # [32.0, 68.0, 98.6, 212.0]Exemple 3 : Transformer des chaînes de caractères
map() est particulièrement utile pour manipuler des chaînes de caractères, par exemple pour les mettre en majuscules, les nettoyer ou les formater.
# Mettre en majuscules une liste de prénoms
prenoms = ["alice", "bob", "charlie", "diana"]
prenoms_maj = list(map(str.upper, prenoms))
print(prenoms_maj) # ['ALICE', 'BOB', 'CHARLIE', 'DIANA']
# Supprimer les espaces inutiles
donnees = [" Paris ", " Lyon", "Marseille "]
donnees_propres = list(map(str.strip, donnees))
print(donnees_propres) # ['Paris', 'Lyon', 'Marseille']Lorsque vous passez une méthode comme str.upper sans parenthèses, Python comprend que vous faites référence à la fonction elle-même, et non à son résultat.
Exemple 4 : Utiliser map() avec plusieurs itérables
La fonction map() peut accepter plusieurs itérables. Dans ce cas, la fonction passée en premier argument doit accepter autant de paramètres qu'il y a d'itérables. L'itération s'arrête dès que le plus court des itérables est épuisé (comportement similaire à zip).
# Additionner deux listes élément par élément
liste_a = [1, 2, 3, 4]
liste_b = [10, 20, 30, 40]
sommes = list(map(lambda a, b: a + b, liste_a, liste_b))
print(sommes) # [11, 22, 33, 44]
# Avec trois itérables
x = [1, 2, 3]
y = [4, 5, 6]
z = [7, 8, 9]
resultat = list(map(lambda a, b, c: a + b + c, x, y, z))
print(resultat) # [12, 15, 18]Exemple 5 : Conversion de types avec map()
Un cas d'utilisation très fréquent est la conversion de types. Par exemple, transformer une liste de chaînes de caractères en liste d'entiers.
# Convertir des chaînes en entiers
chaines = ["1", "2", "3", "4", "5"]
entiers = list(map(int, chaines))
print(entiers) # [1, 2, 3, 4, 5]
# Convertir des entiers en chaînes
nombres = [10, 20, 30]
chaines = list(map(str, nombres))
print(chaines) # ['10', '20', '30']
# Convertir des entrées utilisateur
entree = "3 7 12 25 8"
valeurs = list(map(int, entree.split()))
print(valeurs) # [3, 7, 12, 25, 8]Attention : si l'un des éléments ne peut pas être converti (par exemple int("abc")), une exception ValueError sera levée. Pensez à gérer ces cas dans votre code.
Exemple 6 : map() avec des fonctions personnalisées complexes
Vous pouvez utiliser map() avec des fonctions plus élaborées, notamment pour transformer des structures de données comme des dict.
# Transformer une liste de dictionnaires
utilisateurs = [
{"nom": "Dupont", "prenom": "Jean", "age": 30},
{"nom": "Martin", "prenom": "Marie", "age": 25},
{"nom": "Bernard", "prenom": "Luc", "age": 35},
]
def formater_utilisateur(user):
return f"{user['prenom']} {user['nom']} ({user['age']} ans)"
noms_complets = list(map(formater_utilisateur, utilisateurs))
print(noms_complets)
# ['Jean Dupont (30 ans)', 'Marie Martin (25 ans)', 'Luc Bernard (35 ans)']Remarquez l'utilisation des f-string pour formater les chaînes de manière élégante.
map() vs list comprehension
En Python, les list comprehensions (compréhensions de liste) offrent souvent une alternative à map(). Voyons les différences :
| Critère | map() | List comprehension |
|---|---|---|
| Lisibilité | Bonne avec des fonctions nommées | Meilleure pour des expressions simples |
| Performance | Légèrement plus rapide avec des fonctions C natives | Légèrement plus rapide avec des lambdas |
| Évaluation paresseuse | Oui (retourne un itérateur) | Non (crée la liste immédiatement) |
| Filtrage | Non (nécessite filter()) | Oui (clause if intégrée) |
| Plusieurs itérables | Oui, nativement | Nécessite zip() |
Voici un comparatif en code :
nombres = [1, 2, 3, 4, 5]
# Avec map()
resultat_map = list(map(lambda x: x ** 2, nombres))
# Avec list comprehension
resultat_lc = [x ** 2 for x in nombres]
# Les deux donnent : [1, 4, 9, 16, 25]
print(resultat_map == resultat_lc) # TrueEn règle générale, préférez les list comprehensions lorsque la transformation est simple et tient sur une ligne. Utilisez map() lorsque vous avez déjà une fonction nommée à appliquer ou lorsque vous travaillez avec plusieurs itérables.
L'évaluation paresseuse de map()
Un aspect fondamental de map() est qu'elle retourne un itérateur paresseux. Cela signifie que les éléments ne sont calculés que lorsqu'on les consomme. C'est un avantage majeur lorsque vous travaillez avec de grandes quantités de données.
# map() ne calcule rien immédiatement
resultat = map(lambda x: x ** 2, range(1_000_000))
print(resultat) # <map object at 0x...>
# Les éléments sont calculés à la demande
for valeur in resultat:
if valeur > 100:
print(f"Première valeur > 100 : {valeur}")
break
# Première valeur > 100 : 121
# Seuls les 11 premiers éléments ont été calculés !Attention : un objet map ne peut être consommé qu'une seule fois. Une fois parcouru, il est épuisé. Si vous avez besoin de réutiliser les résultats, convertissez-le en list ou en tuple.
# Démonstration de l'épuisement de l'itérateur
resultat = map(lambda x: x * 2, [1, 2, 3])
print(list(resultat)) # [2, 4, 6]
print(list(resultat)) # [] ← l'itérateur est épuisé !Cas d'utilisation avancés
Combiner map() avec d'autres fonctions
Vous pouvez chaîner map() avec d'autres fonctions comme filter(), zip ou enumerate pour créer des pipelines de transformation de données puissants.
# Chaîner map() et filter()
nombres = range(1, 21)
# Étape 1 : ne garder que les nombres pairs (filter)
# Étape 2 : les mettre au carré (map)
resultat = list(map(lambda x: x ** 2, filter(lambda x: x % 2 == 0, nombres)))
print(resultat) # [4, 16, 36, 64, 100, 144, 196, 256, 324, 400]Utiliser map() avec des classes
Puisque map() accepte n'importe quelle callable, vous pouvez l'utiliser avec des constructeurs de class pour créer des instances d'objets.
class Point:
def __init__(self, x, y):
self.x = x
self.y = y
def __repr__(self):
return f"Point({self.x}, {self.y})"
# Créer des points à partir de coordonnées
coords_x = [1, 2, 3, 4]
coords_y = [10, 20, 30, 40]
points = list(map(Point, coords_x, coords_y))
print(points) # [Point(1, 10), Point(2, 20), Point(3, 30), Point(4, 40)]map() avec None comme fonction
En Python 2, passer None comme fonction à map() revenait à utiliser zip. En Python 3, cette syntaxe n'est plus supportée et lèvera une TypeError.
# Python 3 - Ceci ne fonctionne PAS
# map(None, [1, 2, 3]) # TypeError: 'NoneType' object is not callable
# Utilisez plutôt zip() directement
resultat = list(zip([1, 2, 3], ['a', 'b', 'c']))
print(resultat) # [(1, 'a'), (2, 'b'), (3, 'c')]Bonnes pratiques avec map()
Voici les recommandations essentielles pour utiliser map() efficacement dans vos projets Python :
- Privilégiez les fonctions nommées : si votre lambda devient trop complexe (plus d'une expression), définissez une fonction avec def pour garder votre code lisible.
- N'oubliez pas la conversion :
map()retourne un itérateur, pas une liste. Utilisezlist(),tuple()ou parcourez-le avec une boucle si vous avez besoin des résultats concrets. - Préférez les list comprehensions pour les cas simples :
[x * 2 for x in nombres]est souvent plus lisible quelist(map(lambda x: x * 2, nombres)). - Exploitez l'évaluation paresseuse : lorsque vous travaillez avec de grandes quantités de données, ne convertissez pas inutilement le résultat en liste.
- Utilisez les fonctions built-in :
map(int, liste)oumap(str.strip, liste)sont des cas oùmap()brille par sa concision. - Documentez vos transformations : ajoutez des commentaire ou des docstring pour expliquer les transformations complexes.
Questions fréquentes
Quelle est la différence entre map() et une boucle for en Python ?
La fonction map() applique une transformation à chaque élément d'un itérable de manière déclarative, tandis qu'une boucle for est impérative. map() retourne un itérateur paresseux, ce qui la rend plus efficace en mémoire pour de grands ensembles de données. De plus, map() est généralement plus concise et peut être légèrement plus rapide lorsqu'elle utilise des fonctions natives en C (comme int, str, len). En revanche, une boucle for offre plus de flexibilité pour des logiques complexes impliquant des conditions ou des effets de bord.
Peut-on utiliser map() avec un dictionnaire ?
Oui, mais il faut savoir que lorsque vous passez un dict à map(), l'itération se fait sur les clés du dictionnaire par défaut. Pour itérer sur les valeurs, utilisez dict.values(), et pour les paires clé-valeur, utilisez dict.items(). Par exemple : list(map(str.upper, mon_dict.keys())) transformera toutes les clés en majuscules.
map() modifie-t-elle la liste d'origine ?
Non, map() ne modifie jamais l'itérable d'origine. Elle crée un nouvel objet map contenant les résultats de la transformation. C'est un comportement cohérent avec les principes de la programmation fonctionnelle, où les données sont immuables. Si vous souhaitez modifier la liste d'origine, vous devrez réaffecter le résultat : ma_liste = list(map(transformation, ma_liste)).
Comment apprendre à maîtriser map() et la programmation fonctionnelle en Python ?
Pour maîtriser map() et l'ensemble des concepts de programmation fonctionnelle en Python, la pratique régulière est indispensable. Nous vous recommandons de suivre notre formation dédiée à Python sur Believemy, qui couvre en détail les fonctions natives comme map(), filter() et reduce(), avec de nombreux exercices pratiques pour consolider vos compétences.