Funzioni Lambda in Python: 3 Esercizi Pratici (con Soluzioni e Spiegazioni)

Cerca:

Generic selectors
Exact matches only
Search in title
Search in content
Post Type Selectors
lambda python esempi

Quante volte ti sei trovato a scrivere una funzione di tre o quattro righe solo per doverla usare una volta sola e poi dimenticarla da qualche parte nel file?

Le funzioni lambda in Python servono esattamente a questo: snellire il codice, evitare di inquinare lo script con definizioni inutili e risolvere problemi “al volo”.
In questo articolo vedremo tre esercizi pratici, dal più semplice al più insidioso, per capire quando e come usare queste funzioni anonime.

Pubblicità

Esercizio 1: Il Quadrato Semplice (e la regola d’oro)

La Sfida: Stai sviluppando uno script per un laboratorio di fisica e devi calcolare rapidamente il quadrato di una serie di misure. Scrivi una funzione lambda che restituisca il quadrato di un numero e usala con map() per elevare al quadrato i valori della lista [3, 5, 7, 9].

La Soluzione:

# Lista di input
numeri = [3, 5, 7, 9]

# Applico map passando direttamente la lambda (best practice)
risultati = map(lambda x: x * x, numeri)

# Converto l'iteratore in lista per stampare i valori
lista_quadrati = list(risultati)
print(lista_quadrati)  
 Output: [9, 25, 49, 81]

Dietro le quinte:

Una lambda è una funzione anonima definita in una sola riga: lambda argomenti: espressione.

Non serve scrivere return perché il risultato viene restituito in automatico. Usata insieme a map(), permette di applicare una logica a ogni elemento di un iterabile risparmiando molta memoria.

💡 In sintesi: La lambda è un’espressione “usa-e-getta” perfetta per trasformare rapidamente una lista di dati tramite map().

Domanda di riflessione: Qual è la vera differenza tra una funzione definita con def e una lambda?

Risposta: La differenza pratica è che def crea uno statement complesso (con cicli, più righe, gestione degli errori), ha un nome ufficiale e compare nei log di errore. La lambda è solo un’espressione.

Attenzione: assegnare una lambda a una variabile (es. quad = lambda x: x*x) è considerato un “peccato” dalla PEP 8 di Python. Se devi darle un nome, usa def! Le lambda vanno usate “inline”.

⚠️ Approfondimento: Perché non dovresti mai dare un nome a una Lambda

Mentre ti eserciti, potresti essere tentato di scrivere qualcosa come quadrato = lambda x: x * x.

Funziona? Sì. È un buon codice Python? No.

La PEP 8, il manuale di stile ufficiale di Python, contiene una regola specifica (la E731) che sconsiglia caldamente di assegnare una lambda a una variabile. Il motivo è semplice: se una funzione ha un nome, non dovrebbe essere “anonima”.

Ecco i tre motivi principali per cui assegnare nomi alle lambda è considerato un “peccato” di programmazione:

1. L’incubo del Debugging

Il limite più grande è tecnico. Quando definisci una funzione con def, Python le assegna un nome ufficiale (attributo __name__). Quando crei una lambda, per Python il suo nome è sempre e solo <lambda>.

Se il tuo codice si rompe, il traceback (il messaggio di errore) ti dirà:

  • Con def: Errore nella funzione calcola_distanza alla riga 10. (Chiaro e veloce).

  • Con lambda assegnata: Errore nella funzione <lambda> alla riga 10.

Se hai dieci lambda nel tuo script, buona fortuna a capire quale sia quella che ha generato il problema!

Forse potrebbe interessarti anche:  Dal Codice al Cash Flow: Il Modello Economico-Finanziario di una Startup AI

2. Una contraddizione logica

Le lambda nascono per essere funzioni anonime usa-e-getta. Se senti il bisogno di dare un nome a una logica (come quadrato o filtro_eta), significa che quella logica è abbastanza importante da meritare una struttura propria. Usare una lambda e poi darle un nome è come comprare un piatto usa-e-getta e poi cercare di lavarlo e conservarlo in credenza: un controsenso.

3. Niente “Docstring” o Aiuti

Le funzioni definite con def sono molto più generose. Ti permettono di:

  • Aggiungere Docstring (commenti multiriga che spiegano cosa fa la funzione).

  • Usare i Type Hints (per dire a Python che tipi di dati ti aspetti, es. x: int).

  • Scrivere logiche su più righe per non affaticare la vista.

Nelle lambda tutto questo è impossibile: sei confinato in una singola, stretta riga di codice.

Quando usare allora le Lambda?

La regola d’oro è: usale “Inline”. Le lambda brillano quando vengono passate direttamente come argomento a un’altra funzione, senza mai essere salvate in una variabile.

✅ Esempio Corretto (Inline):

# La lambda nasce e muore dentro sorted(), non ha nome.
punti_ordinati = sorted(punti, key=lambda p: p[0]**2 + p[1]**2)
❌ Esempio Sconsigliato (Assegnata):
# PEP 8 Error: se serve un nome, usa 'def'
formula_distanza = lambda p: p[0]**2 + p[1]**2 
punti_ordinati = sorted(punti, key=formula_distanza)
In sintesi: se devi chiamarla per nome, usa def. Se devi passarla al volo e poi dimenticartene, usa lambda.

Esercizio 2: Distanza tra due punti nel piano

La Sfida:

Hai una lista di coordinate nel piano cartesiano e devi ordinarle in base alla loro distanza dall’origine (0,0). Scrivi una lambda da usare come “chiave” di ordinamento nella funzione sorted(). Infine, estrai il punto più lontano. Lista: [(3,4), (1,1), (5,12), (0,0), (2,2)]

La Soluzione:

punti = [(3,4), (1,1), (5,12), (0,0), (2,2)]

# Usiamo la lambda direttamente nel parametro key di sorted.
# Distanza al quadrato = x^2 + y^2. 
punti_ordinati = sorted(punti, key=lambda p: p[0]**2 + p[1]**2)
print("Punti ordinati:", punti_ordinati)
# Output: [(0, 0), (1, 1), (2, 2), (3, 4), (5, 12)]

punto_max = punti_ordinati[-1]
# Calcoliamo la distanza reale solo per la stampa finale
distanza_reale = (punto_max[0]**2 + punto_max[1]**2)**0.5
print(f"Punto più lontano: {punto_max} con distanza {distanza_reale:.2f}")
Punti ordinati: [(0, 0), (1, 1), (2, 2), (3, 4), (5, 12)]
Punto più lontano: (5, 12) con distanza 13.00

Dietro le quinte:

Il parametro key di sorted() accetta una funzione. Invece di scrivere una def apposita, gli passiamo una lambda che “insegna” a Python come valutare ogni tupla. Il trucco matematico qui è usare la distanza al quadrato (x2 + y2) senza estrarre la radice. Poiché la radice è monotona crescente, l’ordinamento rimane identico, ma il calcolo è molto più veloce.

💡 In sintesi: Usare una lambda come key in sorted() permette di personalizzare l’ordinamento di strutture complesse senza creare funzioni esterne.

Domanda di riflessione: Cosa succede se la funzione key restituisce valori non confrontabili tra loro?

Forse potrebbe interessarti anche:  Linguaggi Regolari e Automi: Teoria, Applicazioni e Metodo di Thompson per il Riconoscimento di Pattern

Risposta: Python non saprebbe come ordinarli e lancerebbe un TypeError. Affinché sorted() funzioni, la chiave deve generare un ordine totale (numeri con numeri, o stringhe con stringhe). Nota: le liste in Python sono confrontabili tra loro in modo lessicografico, ma si otterrebbe un errore se all’interno delle liste ci fossero tipi misti (es. un intero e una stringa).


Esercizio 3: Categorizzazione con Condizione Ternaria

La Sfida: Un’azienda classifica l’età degli utenti:

  • “giovane” se età < 18

  • “adulto” se 18 ≤ età < 65

  • “anziano” se età ≥ 65 Usa una lambda all’interno di map() per convertire la lista eta = [12, 25, 70, 17, 65] nelle relative etichette. Poi, usa filter() per isolare solo le età dei “giovani”.

La Soluzione:

eta = [12, 25, 70, 17, 65]
# Mappatura con operatore ternario annidato
categorie = list(map(lambda e: "giovane" if e < 18 else ("adulto" if e < 65 else "anziano"), eta))
print("Categorie:", categorie)  
# Output: ['giovane', 'adulto', 'anziano', 'giovane', 'anziano']

# Filtro
giovani = list(filter(lambda e: e < 18, eta))
print("Giovani (età):", giovani)  

Categorie: ['giovane', 'adulto', 'anziano', 'giovane', 'anziano']
Giovani (età): [12, 17]

Dietro le quinte:

Dato che una lambda non supporta il classico blocco if-elif-else multilinea, dobbiamo affidarci all’operatore ternario di Python (valore_se_vero if condizione else valore_se_falso). Se le condizioni sono più di due, possiamo annidarli. filter() invece fa un lavoro diverso: tiene solo gli elementi per i quali la lambda restituisce True.

💡 In sintesi: La lambda può gestire logiche di scelta grazie all’operatore if-else in linea, rendendo immediata la categorizzazione o il filtraggio dei dati.

Domanda di riflessione: Si può scrivere una lambda per verificare pari o dispari? E perché non posso usare un costrutto if...elif classico dentro una lambda?

Risposta: Sì: lambda n: "pari" if n % 2 == 0 else "dispari". Non puoi usare un normale if...elif...else perché la sintassi richiede che la lambda contenga esclusivamente un’espressione che restituisce un valore, non uno statement di controllo del flusso.


🛠️ Quando usare una Lambda?

Per evitare di abusare delle funzioni anonime, applica la regola delle 3 Condizioni.

Puoi usare una lambda solo se tutte e tre sono soddisfatte:

  1. Unicità: La logica serve solo in quel punto preciso del codice e non verrà mai riutilizzata altrove.

  2. Sola Espressione: La logica può essere scritta in una singola riga di codice senza dover usare punti e virgola o acrobazie sintattiche.

  3. Chiarezza Immediata: Il nome degli argomenti e l’operazione sono così intuitivi che non servono commenti per spiegarli.


⏱️ Il “Test dei 5 Secondi”

Questo è il gold standard della leggibilità in Python. Quando scrivi una lambda (magari una complessa con operatori ternari come nell’Esercizio 3), distogli lo sguardo per un momento e poi riguardala:

Se non riesci a capire esattamente cosa fa la lambda in meno di 5 secondi, non deve essere una lambda.

Se ti ritrovi a strizzare gli occhi per seguire le parentesi o i blocchi if-else annidati, fermati: cancella tutto e scrivi una funzione tradizionale con def.

Il te stesso del futuro (quello che dovrà fare manutenzione al codice tra sei mesi) ti ringrazierà infinitamente.

Forse potrebbe interessarti anche:  Python: Ricercare in un dizionario

Riassunto finale dei concetti chiave

Per chiudere l’articolo in bellezza, ecco i punti fermi da portare a casa:

Situazione Strumento consigliato Perché?
Trasformazione rapida in map/filter Lambda Codice compatto e “inline”.
Logica riutilizzabile in più file Def Facile da importare e testare.
Operazioni con cicli o più istruzioni Def La lambda non supporta i blocchi di codice.
Debugging di sistemi critici Def I nomi delle funzioni appaiono nei log di errore.

L.A.M.B.D.A.™🐍

  • Logica usa‑e‑getta
  • Atomicità (una sola espressione)
  • Mantenibilità immediata
  • Brevità senza sacrificare chiarezza
  • Debug limitato → evitare nomi
  • Applicazione inline

Ora che sai quando NON usare una lambda, prova a trasformare l’esercizio 1 usando una List Comprehension. Quale delle due versioni ti sembra più chiara dopo aver applicato il Test dei 5 Secondi?


Applicazioni Pratiche 

  • Esercizio 1 (Data Engineering): L’uso di map() con le lambda è la base concettuale di framework di calcolo distribuito come Spark o dei DataFrame in Pandas (tramite il metodo .apply()). Questo esercizio è interessante perché abitua la mente a pensare in modo funzionale: non modifichiamo i dati iterando con un for, ma applichiamo una trasformazione globale all’intero set di dati in un colpo solo.

  • Esercizio 2 (Ottimizzazione Algoritmica): Questo è un classico problema da Game Development o da calcolo spaziale (Geospatial Analysis). La vera perla dell’esercizio è l’astuzia matematica: evitare il calcolo della radice quadrata (costoso a livello di CPU) per effettuare un semplice ordinamento. In scenari con milioni di punti (es. algoritmi di clustering come K-Means), ottimizzare la lambda eliminando la radice fa risparmiare preziosi secondi di computazione.

  •  Esercizio 3 (Data Cleaning): Questo esercizio simula perfettamente un’operazione di binning (raggruppamento in classi), un’attività quotidiana per i Data Analyst. Il fascino di questo esercizio risiede nel “forzare” i limiti della lambda tramite il ternario annidato. Tuttavia, insegna anche una lezione di design del codice: se inizi ad annidare tre o quattro ternari in una lambda, perdi del tutto la leggibilità e diventa preferibile usare una classica def.

 

Pubblicità