Historique de la question :
La fonction enumerate() est apparue dans Python 2.3 et est maintenant le moyen standard d'accéder simultanément à l'élément et à l'indice de l'élément lors du parcours des collections. Avant l'apparition de enumerate(), les programmeurs créaient souvent leurs propres compteurs ou utilisaient la fonction range(len(sequence)), ce qui était peu pratique et peu lisible.
Problème :
Une boucle for classique ne parcourt que les valeurs. Pour accéder à l'indice, on utilise souvent range(len(...)), ce qui ne fonctionne pas avec tous les objets itérables (par exemple, les générateurs, les chaînes de caractères et les tuples de longueur variable, ainsi que lors de la filtration). Cela conduit à des erreurs et complique le code.
Solution :
enumerate() renvoie des paires (indice, élément), ce qui permet d'obtenir l'indice de l'élément courant même pour des collections non standard ou des générateurs filtrés. La fonction accepte un deuxième argument optionnel — la valeur de départ du compteur.
Exemple de code :
words = ['apple', 'banana', 'cherry'] for idx, word in enumerate(words, 1): print(f"{idx}: {word}") # Sortie : # 1: apple # 2: banana # 3: cherry
Caractéristiques clés :
Pourquoi utilise-t-on souvent enumerate dans les fonctions au lieu de range(len(seq)) ?
Réponse : range(len(seq)) ne fonctionne qu'avec des séquences accessibles par index et ne prend pas en compte les changements de longueur pendant l'itération. De plus, il est moins lisible et fonctionne moins bien ou pas du tout pour les générateurs. enumerate() offre un accès sûr aux paires indice-valeur pour toute collection itérable.
Exemple de code :
# Ne fonctionne pas avec un générateur : gen = (x for x in range(5)) for i in range(len(gen)): print(i) # Erreur : un générateur n'a pas de longueur
Peut-on utiliser enumerate pour modifier les éléments d'une liste pendant la traversée ?
Réponse : Oui, mais il faut itérer par indices pour écrire les valeurs. Sinon, si l'on itère seulement sur les valeurs, vous modifiez une copie de l'objet et non l'original.
Exemple de code :
nums = [1, 2, 3] for idx, val in enumerate(nums): nums[idx] = val * 2 # nums = [2, 4, 6]
Que renverra enumerate si on lui passe un objet qui change pendant l'itération ?
Réponse : Si la collection change pendant la traversée (par exemple, des éléments sont supprimés), le comportement peut être inattendu, car enumerate suit l'itérateur interne, qui peut se désynchroniser. Il est donc déconseillé de modifier la collection pendant l'itération.
range(len(...)) pour des objets sans longueur ou pour ceux dont la longueur peut changer.Cas négatif
Un programmeur parcourt une liste en utilisant range(len(list)) et supprime des éléments en cours de route. Résultat : les indices sont décalés, certains éléments sont sautés.
Avantages :
Inconvénients :
Cas positif
On utilise enumerate(), tout en formant une nouvelle liste des éléments requis ou en modifiant une valeur par indice, mais la taille de la liste ne change pas dans la boucle.
Avantages :
Inconvénients :