Python enumerate() Funzione, spiegata con esempi

Questo tutorial esplora l’uso della funzione enumerate() in Python.

La funzione enumerate() in Python semplifica l’accesso agli elementi di un iterabile, fornendo contemporaneamente i loro indici in modo conciso.

Inizieremo con un’analisi di come iterare elementi e indici usando un ciclo di base, per poi introdurre la sintassi della funzione enumerate() di Python, corredando il tutto con esempi pratici.

Iniziamo subito.

Iterare con il ciclo for in Python

In Python, qualsiasi oggetto che permette di scorrere ed accedere ai suoi singoli elementi è definito iterabile. Di conseguenza, liste, tuple, dizionari e stringhe Python sono tutti iterabili.

Consideriamo come esempio una lista della spesa definita nel codice seguente:

shopping_list = ["frutta","biscotti","cereali","barrette proteiche","post-it"]

In Python, il ciclo for permette di iterare attraverso qualsiasi oggetto iterabile. La sintassi per farlo è:

for elemento in <iterabile>:
    # esegui un'azione sull'elemento

# elemento: variabile di ciclo
# <iterabile>: qualsiasi iterabile Python: lista, tupla, dizionario, stringa ecc.

Ora, utilizzando questa sintassi, iteriamo attraverso shopping_list per accedere ai suoi singoli elementi.

for elemento in shopping_list:
  print(elemento)

# Output
frutta
biscotti
cereali
barrette proteiche
post-it

Questa struttura permette un accesso diretto agli elementi. Tuttavia, a volte si ha la necessità di accedere all’indice di ciascun elemento, oltre all’elemento stesso.

Un modo per farlo è utilizzare una variabile indice, che viene incrementata all’interno del corpo del ciclo, come mostrato sotto:

indice = 0
for elemento in shopping_list:
  print(f"indice:{indice}, {elemento}")
  indice += 1

# Output
indice:0, frutta
indice:1, biscotti
indice:2, cereali
indice:3, barrette proteiche
indice:4, post-it

Tuttavia, questo non è il metodo più efficiente. Se ci si dimentica di aggiornare l’indice, il codice non funzionerà come previsto.

indice = 0
for elemento in shopping_list:
  print(f"indice:{indice}, {elemento}")
  # manca l'aggiornamento dell'indice all'interno del ciclo
  # l'indice non viene mai aggiornato e rimane sempre a 0

# Output
indice:0, frutta
indice:0, biscotti
indice:0, cereali
indice:0, barrette proteiche
indice:0, post-it

Un altro metodo comune per utilizzare il ciclo for è combinandolo con la funzione range(). Lo esploreremo nella prossima sezione.

Utilizzo della funzione range() per accedere all’indice

La funzione len() di Python restituisce la lunghezza di qualsiasi oggetto Python. È possibile utilizzare len(shopping_list) per ottenere la lunghezza di shopping_list, che in questo caso è 5.

len(shopping_list)
# Output: 5

La funzione range() restituisce un oggetto range che può essere utilizzato in un ciclo. Quando si itera attraverso range(stop), si ottengono gli indici 0, 1, 2, …, stop-1.

Impostando stop = len(lista), si ottiene l’insieme degli indici validi. Utilizzando range(), è possibile accedere all’indice e all’elemento corrispondente come segue:

for indice in range(len(shopping_list)):
  print(f"indice:{indice}, elemento: {shopping_list[indice]}")

# Output
indice:0, elemento: frutta
indice:1, elemento: biscotti
indice:2, elemento: cereali
indice:3, elemento: barrette proteiche
indice:4, elemento: post-it

Tuttavia, questo non è il modo più consigliato per accedere sia all’indice che all’elemento in Python.

Sintassi della funzione enumerate() in Python

La funzione enumerate() di Python consente di accedere agli elementi insieme ai loro indici utilizzando questa sintassi generale:

enumerate(<iterabile>, start = 0)

Nella sintassi precedente:

  • <iterabile> è un parametro obbligatorio e può essere qualsiasi iterabile di Python, come una lista o una tupla.
  • start è un parametro opzionale che definisce da quale indice iniziare il conteggio. Se non specificato, il valore predefinito è zero.

Ora, chiamando enumerate() con shopping_list si ottiene un oggetto enumeratore, come mostrato nel codice qui sotto.

enumerate(shopping_list)
<enumerate at 0x7f91b4240410>

Non è possibile iterare direttamente su un oggetto enumeratore. Quindi, lo convertiamo in una lista Python.

list(enumerate(shopping_list))

# Output
[(0, 'frutta'),
 (1, 'biscotti'),
 (2, 'cereali'),
 (3, 'barrette proteiche'),
 (4, 'post-it')]

Un altro metodo per accedere agli elementi di un oggetto enumeratore è utilizzare la funzione next(). In Python, next() restituisce l’elemento successivo di un iteratore.

Internamente, next() funziona chiamando il metodo __next__ sull’oggetto iteratore per recuperare l’elemento successivo.

Assegniamo l’oggetto enumeratore alla variabile shopping_list_enum.

shopping_list_enum = enumerate(shopping_list)

La prima chiamata a next(shopping_list_enum) restituirà l’indice zero e l’elemento corrispondente: la tupla (0, 'frutta').

Ulteriori chiamate a next() restituiranno gli elementi successivi con i loro indici, come descritto qui sotto.

next(shopping_list_enum)
# (0, 'frutta')
next(shopping_list_enum)
# (1, 'biscotti')
next(shopping_list_enum)
# (2, 'cereali')
next(shopping_list_enum)
# (3, 'barrette proteiche')
next(shopping_list_enum)
# (4, 'post-it')

Cosa succede se si chiama next() dopo aver già recuperato tutti gli elementi? Viene generato un errore StopIteration.

next(shopping_list_enum)
# ---------------------------------------------------------------------------
StopIteration                             Traceback (most recent call last)
<ipython-input-16-4220f68f6c7e> in <module>()
----> 1 next(shopping_list_enum)

StopIteration:

La funzione enumerate() restituisce indici ed elementi successivi solo quando necessario, non calcolandoli anticipatamente. Per progetti Python in cui l’efficienza della memoria è un fattore cruciale, si può prendere in considerazione l’uso di enumerate() quando si itera attraverso iterabili di grandi dimensioni.

Esempi della funzione enumerate() in Python

Ora che abbiamo appreso la sintassi di enumerate(), modifichiamo il ciclo for visto in precedenza.

Come abbiamo visto, iterare attraverso un oggetto enumeratore restituisce una tupla con l’indice e l’elemento. È possibile spacchettare questa tupla in due variabili: indice e elemento.

for indice, elemento in enumerate(shopping_list):
  print(f"indice:{indice}, elemento:{elemento}")

# Output
indice:0, elemento:frutta
indice:1, elemento:biscotti
indice:2, elemento:cereali
indice:3, elemento:barrette proteiche
indice:4, elemento:post-it

Ora, vediamo come specificare un valore iniziale personalizzato.

enumerate() con valore iniziale personalizzato

Python utilizza l’indicizzazione a base zero, quindi il valore iniziale è 0 per impostazione predefinita. Tuttavia, se si necessita di indici più leggibili, che partono da 1 o da un altro valore, si può specificare un valore iniziale personalizzato.

Nell’esempio della lista della spesa, se si desidera iniziare a contare da 1, si imposta start = 1.

for indice, elemento in enumerate(shopping_list,1):
  print(f"indice:{indice}, elemento:{elemento}")

# Output
indice:1, elemento:frutta
indice:2, elemento:biscotti
indice:3, elemento:cereali
indice:4, elemento:barrette proteiche
indice:5, elemento:post-it

È importante assicurarsi di specificare il valore iniziale personalizzato come secondo argomento posizionale.

Se si invertono l’ordine dell’iterabile e del valore iniziale, si verifica un errore, come si può vedere nel codice sottostante.

for indice, elemento in enumerate(1,shopping_list):
  print(f"indice:{indice}, elemento:{elemento}")

# Output
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-12-5dbf7e2749aa> in <module>()
----> 1 for indice, elemento in enumerate(1,shopping_list):
      2   print(f"indice:{indice}, elemento:{elemento}")

TypeError: 'list' object cannot be interpreted as an integer

Per evitare tali errori, si può specificare start come argomento per parola chiave, come mostrato di seguito.

for indice, elemento in enumerate(shopping_list, start = 1):
  print(f"indice:{indice}, elemento:{elemento}")

# Output
indice:1, elemento:frutta
indice:2, elemento:biscotti
indice:3, elemento:cereali
indice:4, elemento:barrette proteiche
indice:5, elemento:post-it

Finora, abbiamo visto come utilizzare enumerate() con le liste Python. È possibile utilizzare la funzione anche per iterare stringhe, dizionari e tuple.

Utilizzare enumerate() con tuple Python

Supponiamo che shopping_list sia una tupla. Le tuple in Python sono collezioni simili alle liste, ma sono immutabili. Ciò significa che non possono essere modificate, e tentare di farlo causerà un errore.

Il codice seguente inizializza shopping_list come tupla.

shopping_list = ("frutta","biscotti","cereali","barrette proteiche","post-it")
type(shopping_list)
# Tuple

Se si tenta di modificare il primo elemento della tupla, si riceverà un errore, poiché le tuple in Python sono immutabili.

shopping_list[0] = 'verdura'

# Output
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-2-ffdafa961600> in <module>()
----> 1 shopping_list[0] = 'verdura'

TypeError: 'tuple' object does not support item assignment

▶ Ora, esegui il seguente codice per verificare che la funzione enumerate() funzioni come previsto con le tuple.

shopping_list = ("frutta","biscotti","cereali","barrette proteiche","post-it")
for indice, elemento in enumerate(shopping_list):
    print(f"indice:{indice}, elemento:{elemento}")

Utilizzo di enumerate() con le stringhe Python

È anche possibile utilizzare la funzione enumerate() di Python per iterare stringhe e accedere a caratteri e indici contemporaneamente.

Ecco un esempio.

py_str="Farfalla"
for indice, char in enumerate(py_str):
  print(f"indice {indice}: {char}")

# Output
indice 0: F
indice 1: a
indice 2: r
indice 3: f
indice 4: a
indice 5: l
indice 6: l
indice 7: a

Dall’output, si può notare che i caratteri e i relativi indici (0-7) sono stati stampati correttamente.

Conclusione 👩🏽‍💻

Ecco un riepilogo di ciò che abbiamo imparato.

  • È possibile utilizzare i cicli for per accedere agli elementi, mantenendo un contatore o una variabile indice separata.
  • Volendo, è possibile usare la funzione range() per ottenere gli indici validi e accedere agli elementi tramite indicizzazione.
  • Il metodo consigliato in Python è usare la funzione enumerate() con la sintassi: enumerate(iterabile). Per impostazione predefinita, l’indice inizia da 0.
  • È possibile specificare un valore iniziale con la sintassi enumerate(iterabile, start), per far partire l’indice dal valore di start desiderato.
  • Si può utilizzare enumerate() con tuple, stringhe, dizionari e, in generale, con qualsiasi iterabile in Python.

Spero che questo tutorial sull’uso della funzione enumerate() sia stato utile. Scopri anche come trovare l’indice di un elemento nelle liste Python. Continua a programmare!