lettura facile

Subgeneratori in Python

Un subgeneratore in Python è una funzione generatore che viene utilizzata all'interno di un altro generatore per produrre una sequenza di valori.

A cosa servono i subgeneratori? L'uso dei subgeneratori può semplificare il codice che gestisce operazioni complesse di iterazione, perché ti consente di dividere la logica in parti più piccole e riutilizzabili.

Per definire un subgeneratore, devi scrivere semplicemente una funzione che utilizza l'istruzione yield per produrre valori uno alla volta.

Questa funzione può poi essere chiamata all'interno di un altro generatore.

Spesso nei subgeneratori si utilizza l'istruzione yield from per delegare parte del lavoro di iterazione al subgeneratore.

yeld from subgeneratore

Sia il generatore principale che il subgeneratore elaborano i valori uno alla volta, in sequenza, occupando una quantità di memoria inferiore rispetto a un calcolo iterativo.

Un esempio pratico

Ecco un esempio semplice di subgeneratore e come può essere utilizzato all'interno di un generatore principale.

# Generatore che produce numeri da 1 a n
def generate_numbers(n):
    for num in range(1, n + 1):
        yield num

# Generatore che trova e cede i divisori di un dato numero
def find_divisors(num):
    for i in range(1, num + 1):
        if num % i == 0:
            yield i

# Generatore principale che utilizza 'yield from' per cedere direttamente i divisori di ciascun numero
def numbers_and_divisors(n):
    for num in generate_numbers(n):
        print(f"Divisori di {num}: ", end="")
        # Qui utilizziamo 'yield from' per cedere direttamente i valori del sub generatore
        yield from find_divisors(num)
        print() 

# Esempio di utilizzo con n=10
for divisor in numbers_and_divisors(10):  
    print(divisor, end=" ")

La logica del programma procede in questo modo:

Per ogni numero da 1 a n, il generatore principale (numbers_and_divisors) stampa il numero e inizia a cercare i divisori.

Nota che l'elenco dei numeri da 1 a n viene generato da un altro generatore (generate_number) chiamato dal generatore principale in un ciclo for.

Poi il generatore principale (numbers_and_divisors) uilizza yield from per passare controllo al subgeneratore (find_divisors) che trova e cede al generatore principale ogni divisore del numero, uno dopo l'altro.

Dopo che tutti i divisori di un numero sono stati generati e ceduti, il ciclo nel generatore principale continua con il numero successivo, fino a quando tutti i numeri da 1 a n sono stati elaborati.

In questo esempio n=10 e lo script restituisce i divisori dei numeri da 1 a 10.

Divisori di 1: 1
Divisori di 2: 1 2
Divisori di 3: 1 3
Divisori di 4: 1 2 4
Divisori di 5: 1 5
Divisori di 6: 1 2 3 6
Divisori di 7: 1 7
Divisori di 8: 1 2 4 8
Divisori di 9: 1 3 9
Divisori di 10: 1 2 5 10

Questo script dovrebbe aiutarti a capire come funziona un subgeneratore e l'enorme utilità che apporta in un programma Python.

Se tu volessi calcolare i divisori dei numeri da 1 a un miliardo con un calcolo iterativo, il tuo programma occuperebbe una notevole quantità di memoria del computer. Utilizzando i generatori lo spazio di memoria occupato si riduce notevolmente, perché i valori sono restituiti uno alla volta dai generatori e dai subgeneratori.




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




FacebookTwitterLinkedinLinkedin