max() en Python - key, default et pièges à éviter

Noël Besnard .

28 octobre 2026

Schéma illustrant l'itération sur un dictionnaire Python pour trouver la valeur maximale.

Pour trouver le plus grand élément d’une liste, d’un tuple ou même d’un générateur, la fonction max() de Python est généralement le choix le plus simple. Elle permet aussi de comparer des objets selon un critère précis, de gérer une collection vide et de récupérer directement l’élément complet, pas seulement sa valeur. Je détaille ici les syntaxes utiles, les cas liés aux dictionnaires et les erreurs que je vois le plus souvent.

La méthode la plus directe pour trouver la valeur maximale

  • max(iterable) renvoie le plus grand élément d’une collection.
  • Avec key, la comparaison repose sur un critère personnalisé.
  • L’argument default évite l’erreur sur une collection vide.
  • Pour un dictionnaire, max(dictionnaire) compare les clés, pas les valeurs.
  • La fonction parcourt les éléments en O(n) sans modifier la collection.

La fonction max() en Python trouve le plus grand élément d'un itérable ou parmi plusieurs arguments.

Comprendre le fonctionnement de max()

La forme la plus courante est très courte. On transmet un itérable, c’est-à-dire un objet que Python peut parcourir élément par élément, puis la fonction renvoie l’élément considéré comme le plus grand.

nombres = [12, 4, 19, 7]
resultat = max(nombres)

print(resultat)
# 19

Cette syntaxe fonctionne avec une liste, un tuple, un ensemble, une chaîne de caractères, un objet range ou un générateur. Dans mes scripts, je privilégie cette approche dès que la comparaison est évidente, car elle est lisible, rapide et immédiatement compréhensible.

Une collection ou plusieurs arguments

max() accepte également au moins deux arguments positionnels. Les deux écritures suivantes donnent le même résultat, mais elles ne correspondent pas exactement au même usage.

max([8, 14, 3])
# 14

max(8, 14, 3)
# 14

Avec un seul argument, Python attend un objet itérable. Avec plusieurs arguments, il compare directement les valeurs fournies. Une erreur fréquente consiste à écrire max(8), car un entier n’est pas parcourable. Si les valeurs se trouvent déjà dans une liste, utilisez simplement max(ma_liste).

Utiliser key pour comparer selon le bon critère

La vraie puissance de cette fonction apparaît avec l’argument nommé key. Il reçoit une fonction appelée pour chaque élément afin de produire la valeur utilisée pour la comparaison. Le résultat retourné reste toutefois l’élément original.

mots = ["ordinateur", "IA", "réseau", "sécurité"]

plus_long = max(mots, key=len)

print(plus_long)
# ordinateur

Python compare ici les longueurs des mots, mais renvoie le mot lui-même. Je trouve cette distinction essentielle, car elle évite de transformer inutilement une liste avec map() ou une boucle intermédiaire.

Comparer des dictionnaires ou des objets

Pour une liste de dictionnaires, key permet de sélectionner le champ pertinent. Le code suivant récupère le produit le plus cher tout en conservant toutes ses informations.

produits = [
    {"nom": "Clavier", "prix": 49.90},
    {"nom": "Écran", "prix": 229.00},
    {"nom": "Souris", "prix": 34.90}
]

plus_cher = max(produits, key=lambda produit: produit["prix"])

print(plus_cher)
# {'nom': 'Écran', 'prix': 229.0}

La valeur de key doit accepter un seul argument. Une fonction lambda convient pour un besoin ponctuel, tandis qu’une fonction nommée devient plus intéressante lorsque le critère est réutilisé ou mérite un nom explicite.

def prix_produit(produit):
    return produit["prix"]

plus_cher = max(produits, key=prix_produit)

En cas d’égalité, Python renvoie le premier élément rencontré. Ce comportement est pratique lorsque l’ordre d’arrivée représente une priorité. Si ce choix ne vous convient pas, il faut définir une règle secondaire dans la clé de comparaison.

Appliquer max() aux listes, chaînes et dictionnaires

La fonction s’adapte à la plupart des structures Python, mais le résultat dépend toujours de ce que contient réellement l’itérable. C’est souvent là que se cachent les mauvaises surprises.

Nombres et valeurs négatives

temperatures = [-7, -2, -12, -1]

print(max(temperatures))
# -1

Les nombres négatifs ne demandent aucun traitement particulier. Le nombre maximal est simplement celui qui se trouve le plus à droite sur la droite numérique, même si toutes les valeurs sont inférieures à zéro.

Chaînes de caractères

mots = ["Paris", "Lyon", "Bordeaux"]

print(max(mots))
# Paris

Avec des chaînes, la comparaison suit l’ordre lexicographique, proche de l’ordre alphabétique, mais sensible aux majuscules, aux accents et aux règles Unicode. Pour ignorer la casse, je préfère utiliser casefold(), plus robuste que lower() pour les textes internationaux.

mots = ["zèbre", "Avion", "École"]

resultat = max(mots, key=str.casefold)
print(resultat)
# zèbre

Lire aussi : Supprimer les NaN d'une liste Python - La méthode fiable

Dictionnaires

Un dictionnaire parcouru directement fournit ses clés. Ainsi, max(scores) cherche la clé la plus grande, et non la note maximale.

scores = {
    "Alice": 18,
    "Benoît": 15,
    "Chloé": 19
}

meilleure_note = max(scores.values())
meilleur_eleve = max(scores, key=scores.get)

print(meilleure_note)
# 19

print(meilleur_eleve)
# Chloé

Lorsque j’ai besoin du nom et de la valeur en même temps, items() rend le code plus explicite. Chaque élément est alors un tuple composé de la clé et de la valeur.

meilleur = max(scores.items(), key=lambda paire: paire[1])

print(meilleur)
# ('Chloé', 19)

Éviter les erreurs avec default et les données irrégulières

Sur un itérable vide, max() lève une exception ValueError. Ce comportement est logique, puisqu’il n’existe aucun élément à comparer, mais il faut le prévoir lorsqu’une donnée provient d’un fichier, d’une API ou d’une requête filtrée.

valeurs = []

resultat = max(valeurs, default=None)

print(resultat)
# None

default est renvoyé uniquement si l’itérable est vide. Choisissez une valeur qui a un sens métier clair. Retourner automatiquement 0 peut être dangereux si zéro signifie réellement une mesure valide ou si toutes les valeurs attendues sont négatives.

Les éléments doivent aussi être comparables entre eux. Mélanger des entiers et des chaînes provoque généralement une erreur de type.

donnees = [10, "20", 30]

# TypeError lors de l'appel à max(donnees)

Il faut également traiter les valeurs None avant la comparaison. Une compréhension filtrée suffit dans un cas simple, tandis qu’un contrôle plus explicite sera préférable si l’absence de donnée doit être signalée à l’utilisateur.

valeurs = [12, None, 8, 21]

maximum = max(
    (valeur for valeur in valeurs if valeur is not None),
    default=None
)

print(maximum)
# 21

Enfin, un générateur est consommé pendant le parcours. Après un appel à max(), il ne reste donc plus nécessairement de valeurs disponibles. C’est un détail discret, mais important dans les traitements de flux ou de fichiers volumineux.

Choisir entre max(), sorted() et heapq

Pour obtenir un seul élément maximal, trier toute la collection serait inutile. max() parcourt les n éléments une seule fois, avec une complexité temporelle de O(n) et une mémoire supplémentaire généralement constante.

Besoin Solution adaptée Pourquoi
Un seul élément maximal max() Parcours linéaire et code simple
Tous les éléments classés sorted() Retourne une nouvelle liste ordonnée
Les k plus grands éléments heapq.nlargest() Plus adapté à une sélection partielle
Le maximum et sa position max(enumerate(...), key=...) Conserve l’index et la valeur

Pour récupérer la position du maximum, j’utilise souvent enumerate() plutôt qu’une recherche séparée. Le résultat est un couple contenant l’index et la valeur.

notes = [14, 17, 12, 19, 16]

index, meilleure_note = max(enumerate(notes), key=lambda element: element[1])

print(index, meilleure_note)
# 3 19

La seule vraie raison de préférer sorted() est donc d’avoir besoin du classement complet. Pour les trois meilleurs résultats, heapq.nlargest(3, valeurs) exprime mieux l’intention que le tri intégral de plusieurs milliers d’éléments.

Le réflexe simple pour écrire un code fiable

Dans la majorité des cas, je commence par max(iterable), puis j’ajoute key dès que le plus grand élément doit être défini selon un champ, une longueur ou une transformation. Je réserve default aux collections dont le vide est réellement possible, en choisissant une valeur de repli cohérente avec le domaine.

Retenez surtout trois points. max() renvoie l’élément, pas nécessairement la clé de comparaison, le dictionnaire fournit ses clés lorsqu’il est parcouru directement, et une collection vide doit être gérée explicitement. Avec ces règles, cette petite fonction devient un outil très solide pour les scripts Python, les traitements de données et les services automatisés.

Questions fréquentes

max(dictionnaire) compare les clés, et non les valeurs. Pour obtenir la note maximale, utilisez max(scores.values()), ou max(scores, key=scores.get) pour récupérer la clé correspondante. Avec scores.items(), vous pouvez obtenir le couple clé-valeur complet.
Utilisez l’argument key avec une fonction qui reçoit un élément et renvoie le critère de comparaison. Par exemple, max(produits, key=lambda produit: produit["prix"]) renvoie le dictionnaire du produit le plus cher, pas seulement son prix. En cas d’égalité, le premier élément rencontré est conservé.
Ajoutez l’argument default, qui sera renvoyé uniquement si l’itérable est vide, comme dans max(valeurs, default=None). Choisissez une valeur cohérente avec le contexte, car utiliser automatiquement 0 peut être trompeur lorsque les valeurs valides sont négatives ou lorsque zéro a une signification réelle.
max() convient pour trouver un seul élément en O(n), avec un parcours unique et généralement une mémoire constante. Utilisez sorted() si vous avez besoin de classer tous les éléments, et heapq.nlargest() pour sélectionner les k plus grandes valeurs sans trier toute la collection. Pour obtenir aussi la position du maximum, combinez max() avec enumerate().
Évaluer l'article

Moyenne: 5.0 / 5 · 1 évaluation

Tags

max() itérables dictionnaires générateurs fonctions lambda
Autor Noël Besnard
Noël Besnard
Je m'appelle Noël Besnard et je possède 7 ans d'expérience dans le domaine de la technologie, en particulier en ce qui concerne le web, l'intelligence artificielle, les réseaux et la sécurité. Mon intérêt pour ces sujets a commencé dès mon adolescence, lorsque j'ai découvert le potentiel incroyable des nouvelles technologies pour transformer notre quotidien. J'aime explorer les défis que posent ces avancées et partager des solutions accessibles pour aider les lecteurs à mieux comprendre ces enjeux. Au fil des ans, j'ai eu l'occasion d'écrire sur divers aspects de la tech, en mettant l'accent sur la clarté et la précision. Je m'efforce de vérifier mes sources et de comparer les informations afin de proposer un contenu à jour et fiable. Mon objectif est de rendre des sujets complexes plus simples et compréhensibles, tout en suivant les dernières tendances du secteur. Je suis ravi de partager mes connaissances et d'accompagner les lecteurs dans leur exploration des technologies qui façonnent notre avenir.
Commentaires (0)
Ajouter un commentaire