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.

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.