Storia della domanda
La funzione enumerate() è stata introdotta in Python per consentire un'iterazione comoda e idiomatica sugli elementi di una sequenza, ottenendo contemporaneamente l'indice corrente. Questo è particolarmente importante, poiché prima si raccomandava spesso di gestire manualmente un contatore separato, il che era considerato non idiomatico e meno leggibile.
Problema
Nei cicli, è spesso necessario conoscere non solo il valore corrente, ma anche il suo indice nella sequenza. La gestione manuale degli indici utilizzando una variabile separata (i) e chiamando range(len(seq)) porta a errori (disallineamenti tra indici e valori, duplicazione del codice) e riduce la leggibilità.
Risposta
enumerate() restituisce un iteratore pigro, che a ogni passaggio restituisce una tupla (indice, valore) dell'elemento corrente. Con essa, è possibile lavorare in modo elegante e affidabile con gli indici:
colors = ['red', 'green', 'blue'] for idx, color in enumerate(colors): print(idx, color)
L'iterazione inizia da zero, ma è possibile specificare qualsiasi valore iniziale:
for idx, color in enumerate(colors, start=1): print(idx, color)
Caratteristiche chiave:
enumerate() funziona con qualsiasi sequenza iterabile, restituendo una tupla (indice, elemento)start, il che può essere comodoÈ possibile disabilitare il ritorno dell'indice e mantenere solo i valori quando si utilizza enumerate()?
No, enumerate() restituisce sempre coppie (indice, valore). Se si desidera solo il valore, utilizzare un normale ciclo for:
for value in my_list: print(value)
È possibile utilizzare enumerate() con oggetti non indicizzabili, come i generatori?
Sì, enumerate() funziona con qualsiasi oggetto iterabile, compresi i generatori. L'indicizzazione avverrà in base all'ordine in cui compaiono i valori:
def mygen(): for i in range(3): yield chr(ord('a')+i) for idx, val in enumerate(mygen()): print(idx, val) # 0 a, 1 b, 2 c
È possibile assegnare automaticamente un indice di partenza diverso da 0 e cosa succede con valori negativi?
Sì, enumerate() ha un argomento start. Se si passa un valore negativo, l'indicizzazione inizierà da quel valore:
for idx, x in enumerate(['a', 'b', 'c'], start=-3): print(idx, x) # -3 a, -2 b, -1 c
range(len(seq)) invece di enumerate() per scorrere una lista — così il codice diventa meno idiomaticoNel team si mantiene un grande codice, e si usa spesso:
for i in range(len(mylist)): process(i, mylist[i])
Pro:
Contro:
Dopo il refactoring, si passa a:
for idx, val in enumerate(mylist): process(idx, val)
Pro:
Contro: