Introduzione
In Python, i set sono strutture dati molto utili quando devi lavorare con collezioni di elementi unici e vuoi eseguire controlli rapidi su appartenenza, esclusione o confronto tra gruppi di dati. Rispetto a liste e tuple, i set non mantengono l’ordine e non accettano duplicati, ma offrono un vantaggio fondamentale: le operazioni di ricerca sono generalmente molto veloci.
In questo tutorial ci concentriamo su un sotto-argomento pratico e spesso sottovalutato: l’uso dei set per verificare rapidamente se un elemento appartiene a un gruppo, e per confrontare differenze tra insiemi di dati reali. È un approccio molto utile, ad esempio, quando devi:
- controllare se un utente ha già completato una certa azione;
- verificare se un prodotto appartiene a una categoria consentita;
- confrontare tag, permessi, ruoli o codici;
- individuare elementi mancanti o extra tra due collezioni.
Vedremo un esempio realistico con dati di accesso a una piattaforma, così da capire come i set possano semplificare il codice e renderlo più efficiente.
Codice completo
# Esempio: gestione accessi a un portale di formazione
# Obiettivo:
# 1. Verificare se un utente ha accesso a una funzione
# 2. Confrontare due gruppi di utenti
# 3. Trovare chi ha accesso a tutto e chi manca da un gruppo
# Utenti registrati al portale
utenti_registrati = {
"alice",
"bruno",
"chiara",
"davide",
"elena",
"francesco"
}
# Utenti che hanno completato il corso base
corso_base = {
"alice",
"chiara",
"elena",
"giulia"
}
# Utenti che hanno completato il corso avanzato
corso_avanzato = {
"alice",
"davide",
"elena",
"martina"
}
# 1) Controllo rapido di appartenenza
utente_da_verificare = "chiara"
if utente_da_verificare in utenti_registrati:
print(f"{utente_da_verificare} è registrata nel portale.")
else:
print(f"{utente_da_verificare} non è registrata.")
# 2) Intersezione: utenti presenti in entrambi i corsi
completi = corso_base & corso_avanzato
print("Utenti che hanno completato sia il corso base che quello avanzato:", completi)
# 3) Differenza: utenti del corso base che non hanno fatto l´avanzato
solo_base = corso_base - corso_avanzato
print("Utenti che hanno fatto solo il corso base:", solo_base)
# 4) Differenza inversa: utenti dell´avanzato che non hanno fatto il base
solo_avanzato = corso_avanzato - corso_base
print("Utenti che hanno fatto solo il corso avanzato:", solo_avanzato)
# 5) Verifica se un set è sottoinsieme di un altro
# Chi ha completato l´avanzato deve aver completato anche il base?
if corso_avanzato.issubset(corso_base):
print("Tutti gli utenti dell´avanzato sono anche nel base.")
else:
print("Ci sono utenti nell´avanzato che non risultano nel base.")
# 6) Individuare utenti registrati che non hanno completato nessun corso
utenti_con_corsi = corso_base | corso_avanzato
senza_corsi = utenti_registrati - utenti_con_corsi
print("Utenti registrati senza corsi completati:", senza_corsi)
# 7) Esempio pratico: controllare accesso a una funzione premium
funzioni_premium = {"alice", "elena"}
def puo_accedere_premium(nome_utente: str) -> bool:
return nome_utente in funzioni_premium
for utente in ["alice", "bruno", "elena", "martina"]:
print(f"{utente}: accesso premium = {puo_accedere_premium(utente)}") Spiegazione
Il punto forte dei set è la velocità nel controllo di appartenenza. Quando scrivi utente_da_verificare in utenti_registrati, Python usa una struttura ottimizzata per capire subito se l’elemento esiste. Questo è molto più efficiente rispetto a cercare lo stesso valore in una lista lunga, soprattutto quando i dati crescono.
1. Controllo di appartenenza
L’operatore in è una delle operazioni più comuni sui set. È perfetto per risposte booleane: sì o no, presente o assente, autorizzato o non autorizzato.
Nel nostro esempio, verificare se "chiara" è in utenti_registrati permette di validare rapidamente l’accesso senza dover scorrere manualmente tutta la collezione.
2. Intersezione tra set
L’intersezione, ottenuta con & oppure con intersection(), restituisce gli elementi comuni tra due set. Qui serve a scoprire quali utenti hanno completato entrambi i corsi.
Questo tipo di operazione è molto utile in scenari reali come:
- utenti presenti in due gruppi di permessi;
- prodotti disponibili in due magazzini;
- tag condivisi tra due articoli.
3. Differenza tra set
La differenza, ottenuta con - oppure con difference(), mostra gli elementi presenti nel primo set ma non nel secondo. Nel codice abbiamo usato questa operazione per separare chi ha fatto solo il base da chi ha fatto solo l’avanzato.
È una tecnica molto utile per individuare:
- elementi mancanti;
- utenti non ancora completati;
- record presenti in una lista ma assenti in un’altra.
4. Sottoinsieme
Il metodo issubset() serve a verificare se tutti gli elementi di un set sono contenuti in un altro. Nel nostro caso, controlliamo se chi ha completato il corso avanzato ha anche completato il base.
Questa verifica è tipica nei sistemi di formazione, nei workflow aziendali e nei controlli di autorizzazione gerarchica.
5. Unione per costruire un insieme complessivo
L’unione, ottenuta con | oppure con union(), combina i due set eliminando eventuali duplicati. Nel tutorial l’abbiamo usata per costruire l’insieme di tutti gli utenti che hanno completato almeno un corso.
Da lì, sottraendo questi utenti da quelli registrati, otteniamo chi non ha ancora completato alcun corso. È un esempio molto concreto di come i set aiutino a risolvere problemi di business con poche righe di codice.
Best practice
- Usa i set quando ti serve unicità: se i duplicati non hanno senso nel tuo dominio, un set è spesso la scelta giusta.
- Preferisci i set per controlli frequenti di appartenenza: se devi fare molti
in, un set è più adatto di una lista. - Converti i dati in set solo quando serve: se hai bisogno dell’ordine originale o di elementi duplicati, un set non è la struttura corretta.
- Scegli nomi chiari: ad esempio
utenti_registrati,corso_base,funzioni_premium. Rendono il codice molto più leggibile. - Evita di modificare un set mentre lo stai iterando: se devi farlo, crea prima una copia o costruisci un nuovo set.
- Usa i metodi espliciti quando migliorano la leggibilità: per esempio
intersection()edifference()possono essere più leggibili degli operatori&e-in contesti complessi.
Un altro consiglio importante: se i dati provengono da file, API o database, valuta sempre se conviene normalizzarli prima di trasformarli in set. Per esempio, potresti voler usare strip() o lower() per evitare che "Alice" e "alice" vengano trattati come valori diversi.
Riepilogo
I set in Python sono molto più di una semplice collezione di elementi unici. Sono uno strumento pratico per:
- verificare rapidamente se un elemento è presente;
- confrontare gruppi di dati;
- trovare elementi comuni, mancanti o esclusivi;
- scrivere codice più pulito ed efficiente.
Nel tutorial abbiamo visto un caso d’uso realistico con utenti e corsi, ma lo stesso approccio si applica a permessi, tag, codici, categorie e molte altre situazioni. Se lavori spesso con dati che devono essere confrontati tra loro, i set possono semplificarti molto la vita.
Approfondisci con risorse ufficiali
- Documentazione Python sui set:
https://docs.python.org/3/library/stdtypes.html#set-types-set-frozenset - Operazioni sugli insiemi:
https://docs.python.org/3/library/stdtypes.html#frozenset - Tutorial ufficiale Python:
https://docs.python.org/3/tutorial/datastructures.html
Studiare i set con casi pratici ti aiuta a riconoscere subito quando sono la soluzione migliore. In molti progetti reali, scegliere il tipo di dato corretto fa la differenza tra un codice confuso e uno elegante, veloce e facile da mantenere.
