back to top

Funzioni Lambda e ricorsione in Python

Funzioni anonime

In Python le funzioni Lamba sono dei particolari costrutti sintattici derivati dal linguaggio Lisp e chiamati anche funzioni anonime; rispetto alle comuni funzioni definite dall’utente esse non sono associate ad un nome, da qui la caratteristica di essere "anonime", non vengono introdotte dalla parola chiave def, prevedendo invece la keyword lambda, e possono essere seguite soltanto da un’unica espressione.

Una delle caratteristiche della funzioni Lambda risiede nel fatto che esse non sono assolutamente necessarie, infatti qualsiasi risultato possa essere ottenuto con una funzione anonima sarà raggiungibile anche tramite una funzione definita dall’utente, ma possono diventare estremamente comode per la risoluzione di piccoli problemi che non di redo si presentano durante la scrittura del codice. Sostanzialmente esse migliorano la produttività del coding in quanto possono essere definite "al volo", in corso d’opera, senza influire pesantemente sulla struttura di un’applicazione.

Le funzioni Lambda accettano un numero indefinito di argomenti ma, come anticipato, supportano una sola espressione; quest’ultima verrà elaborata dall’interprete di Python ai fini della generazione dell’output. Nell’esempio seguente viene proposta una semplice funzione anonima finalizzata alla divisione del valore di una variabile ("dividendo") per un divisore dal valore costante ("5" nel caso specifico).

# Esempio di funzione Lambda
# impiegata per un'operazione matematica

dividi = lambda dividendo: dividendo / 5

print(dividi(10))

In sostanza, nel codice il compito della funzione Lambda è quello di assegnare all’identificatore "dividi" (che non va confuso con il nome della funzione in quanto anonima) l’oggetto restituito dalla funzione, cioè il risultato dell’eleborazione dell’espressione.

Come sostenuto in precedenza, per qualsiasi funzione Lambda è possibile creare una corrispondente funzione definita dall’utente e neanche il caso proposto in precedenza farà eccezione a questa regola:

# Esempio di funzione definita dall'utente
# impiegata per un'operazione matematica

def dividi(dividendo):
   return dividendo / 5

print(dividi(10))

Si noterà come, in pratica, mentre nelle funzioni definite dall’utente la chiamata alla funzione avviene tramite il loro nome, in quelle anonime viene utilizzato invece l’identificatore; detto questo però le due procedure per la chiamata risultano identiche dal punto di vista sintattico.

Funzioni ricorsive

Il concetto della "ricorsione" è collegato a quello della ricorrenza, nel caso delle funzioni è possibile che una un funzione richiami un’altra funzione che, a suo volta, richiamerà indirettamente la prima, ma è anche possibile che una funzione richiami direttamente se stessa. In Python tale casistica rientra nella tipologia delle funzioni ricorsive, cioè funzioni per l’auto-chiamata.

A livello pratico le funzioni ricorsive presentano il vantaggio di consentire la suddivisione di un problema complesso in problemi di minore entità e quindi più facilmente risolvibili, inoltre, in alcuni casi esse mettono al riparo dalla necessità di digitare sorgenti estremamente articolati, magari particolarmente ricchi di annidamenti dovuti all’esigenza di definire lunghe procedure sequenziali, a tutto vantaggio della produttività e della leggibilità del codice.

Nell’esempio seguente verrà presentata una semplice funzione ricorsiva inserita in un’applicazione interattiva il cui scopo è quello di ottenere il fattoriale di un numero, cioè il prodotto di quel numero per tutti i suoi antecedenti; "24" è per esempio il fattoriale di "4" in quanto risultato dell’espressione "1x2x3x4". Essa in sostanza eviterà allo sviluppatore di dover specificare tutte le permutazioni necessarie per ottenere lo stesso risultato, cosa non particolarmente sensata quando ci si trova a gestire un caso come quello proposto di seguito, dove l’input al programma, cioè il valore del quale si dovrà ottenere il fattoriale, verrà stabilito arbitrariamente dall’utilizzatore.

# Utilizzo delle funzioni ricorsive
# per il calcolo del fattoriale di un numero

def fattoriale(n):
   """Il fattoriale di un numero
   indica il prodotto di
   quel numero per tutti i suoi antecedenti"""

   if n == 1:
       return 1
   else:
       return (n * fattoriale(n-1))

res = int(input("Inserisci un numero: "))
if res >= 1:
   print("Il fattoriale di", res, "è", fattoriale(res))

Fattore necessario per il funzionamento delle funzioni ricorsive è l’esistenza di una condizione per la terminazione delle ricorrenze, tale condizione farà in modo che in un determinato momento la funzione non necessiti di ulteriori ricorrenze, avendo in sostanza esaurito il suo compito. Nell’esempio proposto, dato che il valore di "n" subisce un decremento ad ogni ricorrenza ed è previsto un controllo nel caso in cui "n" sia uguale ad "1", la funzione troverà la sua condizione di terminazione al raggiungimento di quest’ultimo.

Pubblicitร 
Claudio Garau
Claudio Garau
Web developer, programmatore, Database Administrator, Linux Admin, docente e copywriter specializzato in contenuti sulle tecnologie orientate a Web, mobile, Cybersecurity e Digital Marketing per sviluppatori, PA e imprese.