Python Set: filtrare elementi con criteri dinamici in modo efficiente

by theArchitect
SHARE
Python Set: filtrare elementi con criteri dinamici in modo efficiente
© Guida-HTML5.it

Introduzione

I set in Python sono strutture dati molto utili quando serve lavorare con collezioni di elementi unici e con operazioni veloci di confronto. Molti sviluppatori li conoscono per la rimozione dei duplicati o per i controlli di appartenenza, ma c’è un uso ancora più pratico e spesso sottovalutato: filtrare dati in base a criteri dinamici.

Questo scenario è comune in applicazioni reali. Ad esempio, puoi dover escludere utenti bloccati, prodotti non disponibili, tag non consentiti, ID già elaborati oppure categorie riservate. In tutti questi casi, un set permette di descrivere i criteri di filtro in modo semplice, leggibile e molto efficiente.

In questo tutorial vedremo come usare i set per costruire filtri dinamici su liste di dati, combinando chiarezza del codice e buone prestazioni. L’obiettivo è imparare un approccio pratico che puoi riutilizzare in progetti reali.

Codice completo

from dataclasses import dataclass

@dataclass
class Prodotto:
    id: int
    nome: str
    categoria: str
    disponibile: bool
    tags: list[str]


# Dati di esempio: un catalogo prodotti
catalogo = [
    Prodotto(1, "Tastiera meccanica", "informatica", True, ["office", "gaming"]),
    Prodotto(2, "Monitor 27 pollici", "informatica", False, ["display", "ufficio"]),
    Prodotto(3, "Borraccia termica", "accessori", True, ["viaggio", "outdoor"]),
    Prodotto(4, "Zaino laptop", "accessori", True, ["ufficio", "viaggio"]),
    Prodotto(5, "Mouse wireless", "informatica", True, ["office", "ergonomia"]),
    Prodotto(6, "Lampada da scrivania", "arredo", False, ["ufficio", "design"]),
]

# Set dinamici che definiscono i criteri di esclusione
categorie_escluse = {"arredo"}
id_gia_elaborati = {2, 6}
tag_non_consentiti = {"gaming", "outdoor"}

# Filtriamo il catalogo:
# - escludiamo i prodotti già elaborati
# - escludiamo quelli appartenenti a categorie vietate
# - escludiamo quelli che contengono tag non consentiti
# - teniamo solo i prodotti disponibili
prodotti_filtrati = [
    prodotto
    for prodotto in catalogo
    if prodotto.id not in id_gia_elaborati
    and prodotto.categoria not in categorie_escluse
    and prodotto.disponibile
    and not (set(prodotto.tags) & tag_non_consentiti)
]

print("Prodotti accettati:")
for prodotto in prodotti_filtrati:
    print(f"- {prodotto.nome} ({prodotto.categoria})")

# Esempio aggiuntivo: aggiornare dinamicamente i criteri
nuovi_id_bloccati = {5}
id_gia_elaborati |= nuovi_id_bloccati

print("nID aggiornati:", id_gia_elaborati)

Spiegazione

Il codice mostra un caso realistico: un catalogo di prodotti da filtrare secondo regole che possono cambiare nel tempo. La parte interessante è che i criteri non sono hard-coded dentro la logica, ma sono rappresentati da set separati:

  • categorie_escluse: contiene le categorie da non considerare;
  • id_gia_elaborati: contiene gli ID già processati, quindi da saltare;
  • tag_non_consentiti: contiene i tag che rendono un prodotto non idoneo.

Questo approccio è utile perché i set supportano controlli di appartenenza molto rapidi. Quando scriviamo prodotto.id not in id_gia_elaborati, Python cerca l’elemento nel set in modo efficiente. Lo stesso vale per categorie e tag.

La parte più interessante è questa condizione:

not (set(prodotto.tags) & tag_non_consentiti)

L’operatore & tra set calcola l’intersezione. Se l’intersezione tra i tag del prodotto e i tag vietati è vuota, significa che il prodotto non contiene tag proibiti. In pratica, stiamo usando i set per esprimere una regola di filtro in modo molto chiaro.

Vediamo il flusso logico:

  • se l’ID è già stato elaborato, il prodotto viene escluso;
  • se la categoria è vietata, il prodotto viene escluso;
  • se il prodotto non è disponibile, il prodotto viene escluso;
  • se ha almeno un tag non consentito, il prodotto viene escluso.

Alla fine otteniamo una lista di prodotti validi. In questo esempio, i set non servono solo a “contenere dati”, ma diventano strumenti per descrivere regole di business in modo compatto.

La seconda parte del codice mostra anche un vantaggio pratico: i criteri possono essere aggiornati facilmente con l’operatore |=, che unisce un nuovo set a quello esistente. Questo è molto utile quando i filtri vengono alimentati da configurazioni esterne, database o input dell’utente.

Best practice

Quando usi i set per filtrare dati, alcune abitudini rendono il codice più robusto e mantenibile:

  • Usa set per criteri che cambiano spesso: liste di esclusione, blacklist, ID già processati, tag vietati.
  • Converti a set solo quando serve: se i dati originali sono liste, trasformarli in set ha senso quando devi fare molte verifiche di appartenenza o confronti.
  • Evita di modificare i set mentre li usi nel filtro: meglio costruire prima i criteri e poi applicarli al dataset.
  • Preferisci nomi espliciti: ad esempio tag_non_consentiti è più chiaro di set1 o blocchi.
  • Usa intersezione e differenza nei casi giusti: l’intersezione è perfetta per scoprire elementi in comune; la differenza è utile per capire cosa resta dopo un’esclusione.

Un altro consiglio importante riguarda la leggibilità. Anche se i set sono molto efficienti, non conviene scrivere condizioni troppo compatte se diventano difficili da leggere. In un progetto reale, spesso è meglio dividere il filtro in passaggi logici separati:

prodotti_validi = []

for prodotto in catalogo:
    if prodotto.id in id_gia_elaborati:
        continue
    if prodotto.categoria in categorie_escluse:
        continue
    if not prodotto.disponibile:
        continue
    if set(prodotto.tags) & tag_non_consentiti:
        continue

    prodotti_validi.append(prodotto)

Questa versione è più lunga, ma può risultare più facile da mantenere, soprattutto quando le regole crescono.

Riepilogo

I set non servono solo a eliminare duplicati o verificare rapidamente se un elemento è presente. Sono anche uno strumento molto efficace per filtrare dati con criteri dinamici.

  • Rappresentano bene blacklist, whitelist e insiemi di esclusione.
  • Permettono controlli veloci con in e not in.
  • Supportano operazioni insiemistiche come intersezione e unione.
  • Rendono il codice più chiaro quando i criteri di filtro sono molteplici.

Se devi gestire dati che cambiano nel tempo, o se vuoi scrivere filtri leggibili e performanti, i set sono una scelta eccellente. In particolare, sono molto adatti quando il problema può essere descritto come confronto tra gruppi di elementi.

Approfondisci con risorse ufficiali

  • Documentazione ufficiale Python sui set: Built-in Types — set
  • Documentazione sulle operazioni sugli insiemi: unione, intersezione, differenza e differenza simmetrica
  • Documentazione ufficiale su dataclasses: utile per creare esempi leggibili con oggetti semplici
  • PEP 8: guida allo stile del codice Python, utile per scrivere filtri chiari e coerenti

Studiare i set con un taglio pratico ti aiuta a riconoscere più facilmente i problemi in cui questa struttura dati è la soluzione migliore. In molti casi, un buon filtro basato su set può semplificare notevolmente il codice e migliorare le prestazioni dell’applicazione.

SHARE