Introduzione
I dizionari sono una delle strutture dati più utili di Python quando devi rappresentare informazioni associative, cioè dati composti da chiavi e valori. Un caso molto pratico è la gestione di un catalogo di prodotti, dove ogni prodotto può avere attributi diversi: nome, prezzo, categoria, disponibilità, varianti di colore o taglia, e così via.
Questo tutorial ti mostra come usare i dizionari per costruire un piccolo sistema di catalogo flessibile, adatto a progetti reali come e-commerce, gestionali, app interne o prototipi API. L’obiettivo non è solo memorizzare dati, ma anche organizzarli bene, aggiornarli in modo sicuro e interrogarli facilmente.
Il sotto-argomento scelto è utile perché spesso i prodotti non sono tutti uguali: alcuni hanno varianti, altri no; alcuni hanno sconti, altri hanno attributi extra. I dizionari permettono di modellare questa variabilità in modo naturale.
Codice completo
from pprint import pprint
# Catalogo prodotti:
# La chiave esterna è il codice prodotto (SKU)
# Il valore è un dizionario con i dati del prodotto
catalogo = {
"TSHIRT-001": {
"nome": "T-shirt basic",
"categoria": "abbigliamento",
"prezzo": 14.90,
"disponibile": True,
"attributi": {
"taglie": ["S", "M", "L", "XL"],
"colori": ["bianco", "nero", "blu"]
}
},
"MUG-010": {
"nome": "Tazza personalizzata",
"categoria": "home",
"prezzo": 9.50,
"disponibile": True,
"attributi": {
"materiale": "ceramica",
"capacita_ml": 350
}
},
"NOTE-200": {
"nome": "Quaderno A5",
"categoria": "ufficio",
"prezzo": 4.20,
"disponibile": False,
"attributi": {
"pagine": 120,
"copertina": "rigida"
}
}
}
def mostra_prodotto(sku):
"""Stampa i dettagli di un prodotto se esiste nel catalogo."""
prodotto = catalogo.get(sku)
if prodotto is None:
print(f"Prodotto {sku} non trovato.")
return
print(f"SKU: {sku}")
print(f"Nome: {prodotto[´nome´]}")
print(f"Categoria: {prodotto[´categoria´]}")
print(f"Prezzo: €{prodotto[´prezzo´]:.2f}")
print(f"Disponibile: {´sì´ if prodotto[´disponibile´] else ´no´}")
print("Attributi:")
for chiave, valore in prodotto["attributi"].items():
print(f" - {chiave}: {valore}")
def aggiorna_prezzo(sku, nuovo_prezzo):
"""Aggiorna il prezzo di un prodotto esistente."""
if sku in catalogo:
catalogo[sku]["prezzo"] = nuovo_prezzo
print(f"Prezzo di {sku} aggiornato a €{nuovo_prezzo:.2f}")
else:
print(f"Impossibile aggiornare: {sku} non esiste.")
def aggiungi_variante(sku, tipo_variante, valore):
"""Aggiunge una variante o un attributo al prodotto."""
if sku not in catalogo:
print(f"Prodotto {sku} non trovato.")
return
attributi = catalogo[sku].setdefault("attributi", {})
attributi[tipo_variante] = valore
print(f"Aggiunto attributo ´{tipo_variante}´ a {sku}.")
def prodotti_per_categoria(categoria):
"""Restituisce una lista di SKU appartenenti a una categoria."""
risultati = []
for sku, prodotto in catalogo.items():
if prodotto["categoria"] == categoria:
risultati.append(sku)
return risultati
def prodotti_disponibili():
"""Restituisce i prodotti disponibili."""
return {
sku: dati
for sku, dati in catalogo.items()
if dati["disponibile"]
}
# Esempi di utilizzo
print("=== DETTAGLIO PRODOTTO ===")
mostra_prodotto("TSHIRT-001")
print("n=== AGGIORNAMENTO PREZZO ===")
aggiorna_prezzo("MUG-010", 8.90)
print("n=== AGGIUNTA VARIANTE ===")
aggiungi_variante("TSHIRT-001", "fit", "regular")
print("n=== PRODOTTI IN CATEGORIA ´abbigliamento´ ===")
print(prodotti_per_categoria("abbigliamento"))
print("n=== PRODOTTI DISPONIBILI ===")
pprint(prodotti_disponibili()) Spiegazione
1. Struttura del catalogo
La variabile catalogo è un dizionario principale. Ogni chiave è uno SKU, cioè un codice univoco prodotto come TSHIRT-001. Il valore associato è un altro dizionario con i dettagli del prodotto.
Questa scelta è molto pratica perché ti consente di trovare un prodotto in modo immediato usando il suo codice. In un catalogo reale, lo SKU è spesso il riferimento più affidabile per identificare un articolo.
2. Dizionari annidati
All’interno di ogni prodotto troviamo un secondo dizionario chiamato attributi. Questo è un esempio di dizionario annidato. Serve quando i dati sono strutturati in più livelli.
Per esempio, una maglietta può avere taglie e colori, mentre una tazza può avere materiale e capacità. Non ha senso forzare tutti i prodotti ad avere gli stessi campi: i dizionari permettono di modellare questa differenza in modo naturale.
3. Accesso sicuro con get()
La funzione mostra_prodotto() usa catalogo.get(sku) invece di catalogo[sku]. È una scelta importante:
catalogo[sku]genera un errore se la chiave non esiste.catalogo.get(sku)restituisceNonese la chiave manca, permettendoti di gestire il caso in modo elegante.
Questo approccio è molto utile quando i dati arrivano da input esterni, file o API.
4. Aggiornamento dei valori
La funzione aggiorna_prezzo() mostra come modificare un valore dentro un dizionario annidato:
catalogo[sku]["prezzo"] = nuovo_prezzo
Qui stai accedendo prima al prodotto, poi al campo prezzo. È una delle operazioni più comuni con i dizionari: leggere, modificare, aggiungere o rimuovere campi.
5. Uso di setdefault()
La funzione aggiungi_variante() utilizza setdefault() per garantire che il dizionario attributi esista. Questo metodo è molto comodo quando non sei sicuro che una chiave sia già presente.
In pratica:
- se
attributiesiste, lo usa; - se non esiste, lo crea con un dizionario vuoto.
È una soluzione pulita per evitare controlli manuali troppo verbosi.
6. Ricerca per categoria
La funzione prodotti_per_categoria() scorre il catalogo con items() e raccoglie gli SKU dei prodotti appartenenti a una categoria specifica. È un esempio classico di filtro sui dati contenuti in un dizionario.
Se invece vuoi ottenere direttamente i prodotti disponibili, la funzione prodotti_disponibili() usa una dictionary comprehension, che è una forma compatta e leggibile per costruire un nuovo dizionario filtrato.
Best practice
- Usa chiavi stabili e univoche: nello scenario dei cataloghi, lo SKU è perfetto perché identifica ogni prodotto in modo affidabile.
- Evita dizionari troppo profondi: i dizionari annidati sono utili, ma se la struttura diventa eccessivamente complessa può essere meglio passare a classi o dataclass.
- Preferisci
get()quando i dati possono mancare: riduce il rischio diKeyErrore migliora la robustezza del codice. - Usa
setdefault()con criterio: è ottimo per inizializzare strutture opzionali, ma non abusarne se il flusso diventa poco chiaro. - Separa dati e logica: il dizionario deve contenere i dati, mentre le funzioni devono occuparsi delle operazioni sul catalogo.
- Valida i valori in ingresso: prima di aggiornare un prezzo o aggiungere un attributo, controlla che il dato sia corretto.
- Usa nomi coerenti: chiavi come
prezzo,categoria,disponibiledevono essere uniformi in tutto il progetto.
Riepilogo
I dizionari in Python non servono solo a cercare valori rapidamente: sono uno strumento flessibile per modellare dati reali. In questo tutorial hai visto come costruire un catalogo di prodotti con attributi variabili, come leggere e modificare i dati, come filtrare i prodotti e come gestire strutture annidate.
Il vantaggio principale è la flessibilità: puoi rappresentare oggetti diversi senza dover creare una struttura rigida per ogni caso. Questo rende i dizionari ideali per prototipi, script di automazione, backend leggeri e gestione di dati semi-strutturati.
Se vuoi fare un passo avanti, puoi estendere questo esempio con:
- salvataggio del catalogo in JSON;
- gestione di sconti e promozioni;
- ricerca per intervallo di prezzo;
- ordinamento dei prodotti per disponibilità o costo;
- integrazione con file CSV o database.
Approfondisci con risorse ufficiali
- Documentazione Python sui dizionari:
https://docs.python.org/3/library/stdtypes.html#mapping-types-dict - Funzioni built-in utili:
https://docs.python.org/3/library/functions.html - PEP 584 - operatori di unione dei dizionari:
https://peps.python.org/pep-0584/ - PEP 468 - preservare l’ordine degli argomenti keyword:
https://peps.python.org/pep-0468/
