Vai al contenuto

Parametri avanzati e lambda

In questa lezione impari a

  • accettare quanti argomenti si vuole con *args
  • accettare argomenti con nome liberi con **kwargs
  • scrivere funzioni lambda
  • ordinare e filtrare con sorted() e filter()

*args: quanti argomenti vuoi

A volte non sai in anticipo quanti valori riceverà una funzione. Con l'asterisco, *args raccoglie tutti gli argomenti in una tupla:

def somma(*numeri):
    totale = 0
    for n in numeri:
        totale += n
    return totale

print(somma(2, 3))          # 5
print(somma(1, 2, 3, 4))    # 10

**kwargs: argomenti con nome liberi

Con due asterischi, **kwargs raccoglie gli argomenti passati con un nome in un dizionario:

def crea_profilo(nome, **dati):
    profilo = {"nome": nome}
    profilo.update(dati)
    return profilo

print(crea_profilo("Anna", eta=16, citta="Torino", sport="nuoto"))

Tutto insieme: l'ordinazione al ristorante

L'ordine dei parametri è sempre questo: normali, *args, con valore predefinito, **kwargs.

def ordina(cliente, *piatti, servizio="sala", **extra):
    print(f"Ordine di {cliente} ({servizio})")
    for piatto in piatti:
        print(f" - {piatto}")
    for chiave, valore in extra.items():
        print(f"   {chiave}: {valore}")

ordina("Marco", "pizza", "tiramisù", servizio="asporto", bibita="acqua", note="senza cipolla")

cliente è obbligatorio, *piatti raccoglie tutti i piatti, servizio vale "sala" se non lo specifichi, **extra raccoglie ogni altra richiesta.

Le funzioni lambda

Una lambda è una piccola funzione senza nome, scritta in una riga sola. Contiene una sola espressione, il cui risultato viene restituito.

quadrato = lambda x: x ** 2
print(quadrato(5))   # 25

# è equivalente a:
def quadrato(x):
    return x ** 2

Le lambda danno il meglio quando servono "al volo", dentro altre funzioni.

Ordinare con sorted()

parole = ["banana", "kiwi", "albicocca", "fico"]
print(sorted(parole))                    # in ordine alfabetico
print(sorted(parole, key=len))           # per lunghezza
print(sorted(parole, key=lambda p: p[-1]))   # per ultima lettera

key indica in base a cosa ordinare.

Filtrare con filter()

numeri = [3, 8, 12, 5, 7, 20]
pari = list(filter(lambda x: x % 2 == 0, numeri))
print(pari)   # [8, 12, 20]

Esercizi

Esercizio 1 – Il massimo. Scrivi una funzione massimo(*numeri) che restituisce il valore più grande senza usare max().

Mostra la soluzione
def massimo(*numeri):
    piu_grande = numeri[0]
    for n in numeri:
        if n > piu_grande:
            piu_grande = n
    return piu_grande

print(massimo(4, 17, 9, 2))   # 17

Esercizio 2 – La media dei voti. Scrivi una funzione media(**voti) che si chiama così: media(italiano=7, matematica=8, inglese=6) e restituisce la media.

Mostra la soluzione
def media(**voti):
    return sum(voti.values()) / len(voti)

print(media(italiano=7, matematica=8, inglese=6))   # 7.0

Esercizio 3 – Classifica. Data una lista di tuple (nome, punti), stampala ordinata dal punteggio più alto al più basso.

Mostra la soluzione
giocatori = [("Anna", 120), ("Luca", 95), ("Marta", 150), ("Ivan", 110)]
classifica = sorted(giocatori, key=lambda g: g[1], reverse=True)
for posizione, (nome, punti) in enumerate(classifica, start=1):
    print(f"{posizione}. {nome} - {punti} punti")

Esercizio 4 – Anagrammi. Scrivi una funzione che dice se due parole sono anagrammi, cioè hanno le stesse lettere in ordine diverso (per esempio "roma" e "amor").

Mostra la soluzione
def anagrammi(a, b):
    return sorted(a.lower()) == sorted(b.lower())

print(anagrammi("Roma", "amor"))   # True
print(anagrammi("casa", "cosa"))   # False

sorted() su una stringa restituisce la lista delle sue lettere in ordine: se le due liste sono uguali, le lettere sono le stesse.