Capitolo 10: Iteratori, Generatori & Comprensioni
Approfondisci il protocollo di iterazione di Python, crea generatori per valutazione pigra e usa comprensioni per trasformazioni concise dei dati.
Scaricachapter10.py
Obiettivi
- Capire il protocollo degli iteratori:
__iter__()
e__next__()
. - Usare iteratori built-in con
iter()
enext()
. - Creare classi iteratori personalizzate.
- Scrivere funzioni generatrici con
yield
. - Usare espressioni generatrici.
- Costruire comprensioni di lista, dizionario e set.
1. Iteratori & Protocollo di Iterazione
Qualsiasi oggetto che implementa __iter__()
e __next__()
è un iteratore:
# le liste sono iterable, non iteratori
lst = [1,2,3]
it = iter(lst) # ottiene l'iteratore
print(next(it)) # 1
print(next(it)) # 2
# StopIteration quando esaurito
Classe iteratore personalizzata:
class Counter:
def __init__(self, limit):
self.limit = limit
self.current = 0
def __iter__(self):
return self
def __next__(self):
if self.current >= self.limit:
raise StopIteration
val = self.current
self.current += 1
return val
for i in Counter(3):
print(i) # 0, 1, 2
2. Funzioni Generatrici
Usa yield
per produrre una sequenza pigramente:
def fib(n):
a, b = 0, 1
for _ in range(n):
yield a
a, b = b, a + b
for num in fib(5):
print(num) # 0, 1, 1, 2, 3
I generatori mantengono automaticamente lo stato e sollevano StopIteration
al termine.
3. Espressioni Generatrici
Sintassi compatta per creare generatori:
# generatore di quadrati
squares = (x*x for x in range(10))
print(next(squares)) # 0
for sq in squares:
print(sq)
4. Comprensioni
a) List Comprehensions
# quadrati dei numeri pari da 0 a 9
even_squares = [x*x for x in range(10) if x % 2 == 0]
b) Dict Comprehensions
# mappa numero al suo quadrato
sq_map = {x: x*x for x in range(5)}
c) Set Comprehensions
# lettere iniziali uniche
names = ["Alice","Bob","Anna"]
first_letters = {name[0] for name in names}
Esercizi
- Implementa una classe iteratore
Fibonacci
che generi numeri di Fibonacci fino an
. - Scrivi un generatore
primes()
che produca numeri primi indefinitamente. - Usa un’espressione generatrice per calcolare pigramente la somma dei quadrati da 1 a 100.
- Appiattisci una lista annidata (ad esempio
[[1,2],[3,4]]
) usando una comprehensions di lista annidata. - Data una mapping dict, scrivi una dict comprehension per invertire chiavi e valori.