lettura facile

Gli oggetti iterabili in Python

In questa lezione del corso Python ti parlo degli oggetti iterabili.

Cos'è un oggetto iterabile? Un oggetto contenitore è "iterabile" se è possibile accedere ai suoi elementi tramite un indice oppure se possiede un metodo che è in grado di restituire un "iteratore" utilizzando un ciclo for. Ad esempio, sono oggetti iterabili le liste, le tuple, le stringhe, i dizionari, i set (insiemi), i generatori, ecc.

In questi oggetti l'iterazione è garantita dalla presenza di alcuni metodi particolari:

  • Il metodo __iter__()
    E' il metodo che restituisce un iteratore.

    oggetto.__iter__()

  • Il metodo __next__()
    E' il metodo che restituisce l'elemento successivo all'interno del contenitore, rispetto alla posizione corrente. Se gli elementi sono stati già restituiti tutti, il metodo solleva un'eccezione "StopIteration" che ferma le iterazioni e conclude il ciclo di lettura.

    oggetto.__next__()

A cosa servono gli oggetti iterabili?

Gli oggetti iterabili sono particolarmente utili quando devi eseguire un'operazione su ciascun elemento di una collezione di dati.

Ad esempio, puoi usare un oggetto iterabile per controllare se una certa parola appare in un testo oppure per calcolare la media o sommare i valori all'interno di una sequenza di dati.

In Python, gli oggetti iterabili sono anche alla base dei generatori e delle comprehension, due strumenti indispensabili per creare un codice compatto, leggibile ed efficiente.

Un esempio pratico

Per capire meglio questi concetti ti faccio un esempio pratico.

Ad esempio, crea un oggetto di tipo string ossia una stringa

>>> stringa = "Python"

Ora verifica se la stringa ha il metodo __iter__() che ti permette di trasformarlo in un oggetto iterabile.

Puoi verificare se un oggetto ha un attributo tramite la funzione hasattr()

>>> hasattr(stringa, '__iter__')
True

La risposta è "True" (vero). Questo vuol dire che la stringa può essere trasformata in un oggetto iterabile.

A questo punto, trasforma la stringa in un oggetto iterabile tramite il metodo __iter__()

>>> obj=stringa.__iter__()

Puoi ottenere lo stesso risultato anche utilizzando la funzione iter() in sostituzione del metodo __iter__()

>>> obj=iter(stringa)

Poi verifica se l'oggetto iterabile "obj" che hai appena creato è anche un iteratore ossia se ha il metodo __next__()

>>> hasattr(obj, '__next__')
True

La risposta è True. Quindi, l'oggetto "obj" è un iteratore.

Ora puoi usare il metodo __next__() per leggere ogni singolo elemento della stringa, uno dopo l'altro.

Alla prima chiamata il metodo next restituisce il primo carattere "P"

>>> obj.__next__()
P

Puoi ottenere lo stesso risultato anche utilizzando la funzione next() in sostituzione del metodo __next__()

>>> next(obj)

Alla seconda chiamata restituisce il secondo carattere della stringa, ossia "y"

>>> obj.__next__()
y

Alla terza chiamata restituisce il terzo carattere della stringa, ossia "t"

>>> obj.__next__()
t

E via dicendo fino all'ultimo carattere della stringa.

La differenza tra gli oggetti iterabili e gli iteratori

A seconda se un oggetto possiede solo uno o entrambi i metodi è detto iterabile o iteratore

  • Un oggetto iterabile ha il metodo iter()
  • Un oggetto iteratore ha sia il metodo iter() che il metodo next()

Pertanto, un iteratore è sempre anche un oggetto iterabile. Viceversa un oggetto iterabile non è detto che sia un iteratore.

Esempio. Un oggetto di tipo set è "iterabile" perché ha il metodo iter() ma non è un "iteratore" perché non possiede il metodo next(). Facciamo un esempio pratico, crea un oggetto di tipo set

>>> s = {1,2,3}

Poi verifica se ha il metodo "iter" tramite la funzione hasattr()

Il risultato è "True", quindi il set è un oggetto iterabile.

>>> hasattr(s,'__iter__')
True

Ora verifica se ha anche il metodo "next"

La risposta è "False". Pertanto, il set non è un iteratore.

>>> hasattr(s,'__next__')
False

Puoi comunque trasformare il set in un iteratore usando il metodo __iter__().

>>> obj = s.__iter__()

Dopo la trasformazione, l'oggetto "obj" è un iteratore perché ha sia l'attributo "iter"

>>> hasattr(obj,'__iter__')
True

che l'attributo "next"

>>> hasattr(obj,'__next__')
True

Ricorda che da uno stesso oggetto iterabile, puoi creare due o più iteratori indipendenti.

Ad esempio, genera due oggetti iteratori a partire dalla stessa lista.

 

>>> s = [1,2,3]
>>> obj1 = s.__iter__()
>>> obj2= s.__iter__()

Pur essendo composti dagli stessi elementi, puoi iterare ogni iteratore (obj1 e obj2) indipendentemente dall'altro, perché sono oggetti diversi.

>>> obj1 is obj2

False

Esempi di Oggetti Iterabili

Ecco alcuni esempi pratici di oggetti iterabili in Python:

1] Le liste

Una lista è una delle strutture di dati che contiene una sequenza di dati dello stesso tipo o di tipi differenti.

  1. lista = [1, 2, 3, 4, 5]
  2. for i in lista:
  3. print(i)

Il ciclo for restituisce gli elementi della lista uno dopo l'altro.

1
2
3
4
5

2] Le tuple

Una tupla è un tipo di dato simile alla lista, ma è immutabile. Una volta definita, non puoi più modificarla durante l'esecuzione del programma o la sessione di lavoro.

  1. tupla = (1, 2, 3, 4, 5)
  2. for i in tupla:
  3. print(i)

Anche in questo caso il ciclo for restituisce una alla volta tutti gli elementi della tupla

1
2
3
4
5

3] Stringhe

Le stringhe sono un altro oggetto iterabile in Python.

  1. stringa = "Python"
  2. for char in stringa:
  3. print(char)

Ogni iterazione accede a ciascun carattere della stringa.

P
y
t
h
o
n

4] Dizionari

Un dizionario è una struttura dati che memorizza dati sotto forma di coppie chiave-valore. Quando si itera su un dizionario, si accede di default alle chiavi.

  1. dizionario = {'uno': 1, 'due': 2, 'tre': 3}
  2. for key in dizionario:
  3. print(key)

Il ciclo stampa tutte le chiavi presenti nel dizionario

uno
due
tre

Tuttavia, si può accedere ai valori o alle coppie chiave-valore utilizzando i metodi appropriati.

Ad esempio, puoi accedere ai valori tramite il metodo values()

  1. dizionario = {'uno': 1, 'due': 2, 'tre': 3}
  2. for value in dizionario.values():
  3. print(value) # Stampa i valori

Questo ciclo stampa tutti valori del dizionario

1
2
3

Per accedere alle coppie chiave-valori puoi usare il metodo items()

  1. dizionario = {'uno': 1, 'due': 2, 'tre': 3}
  2. for key, value in dizionario.items():
  3. print(key, value)

Questo ciclo stampa tutte le chiavi e i valori del dizionario

uno 1
due 2
tre 3

4] File

I file sono un altro esempio di oggetto iterabile perché, una volta aperto, puoi iterare il file per leggere ogni riga di testo (record).

  1. with open("file.txt", "r") as file:
  2. for line in file:
  3. print(line)

In ogni iterazione Python legge una riga del file, una dopo l'altra, fino alla fine del file (End Of File)




Se qualcosa non ti è chiaro, scrivi la tua domanda nei commenti.




FacebookTwitterLinkedinLinkedin