Lezione 12: Dizionari: dati associativi ✅

In questa lezione impari a usare i dizionari in Python (mapping type dict) per gestire coppie chiave→valore in modo veloce e leggibile. Vedremo creazione, accesso, aggiornamento, metodi utili (get, update, pop, setdefault, keys/values/items), iterazione con for, note su ordine di inserimento e prestazioni, oltre a esempi pratici e un esercizio finale. Chiuderemo con FAQ, quiz e collegamento alla prossima lezione su def.


🔗 Ripassi consigliati:
Lezione 2 – Il tuo primo script: Hello, Python!https://www.saperesemplice.com/primo-script-python-hello/
Lezione 3 – Variabili e Tipi di Datohttps://www.saperesemplice.com/variabili-tipi-dato-python/
Lezione 8 – Ciclo whilehttps://www.saperesemplice.com/ciclo-while-python-base/
Lezione 9 – Ciclo for e range()https://www.saperesemplice.com/ciclo-for-range-python/


Dettagli lezione

⏱️ Tempo stimato: 35–45 minuti
🧩 Difficoltà: Facile
🎯 Obiettivi specifici

  • Creare dizionari con letterali {} e costruttore dict().
  • Accedere/aggiornare valori con [], get, update, setdefault; rimuovere con del, pop, popitem, clear.
  • Iterare con for su chiavi, valori e coppie (keys/values/items).
  • Conoscere l’ordine di inserimento (dizionari preservano l’ordine) e le dictionary views.
  • Applicare i concetti con esempi realistici (config, rubrica, conteggi) e un esercizio.

🧱 Cos’è un dizionario (dict)

Un dizionario è una mappa di coppie chiave→valore:

# Creazione
user = {"name": "Alice", "age": 27, "country": "IT"}
empty = {}              # dizionario vuoto
also = dict(name="Bob", age=30)  # costruttore
  • Le chiavi devono essere hashable (immutabili: str, int, tuple di immutabili…).
  • I valori possono essere di qualsiasi tipo (anche liste, altri dict).
  • I dizionari preservano l’ordine di inserimento: iterando ottieni gli elementi nello stesso ordine in cui sono stati aggiunti.
  • L’accesso per chiave è medio O(1) (tabella hash).

Domanda per te: quando useresti una chiave tupla invece di una stringa?


🔎 Accesso, aggiornamento e rimozione

profile = {"username": "alice", "email": "[email protected]"}

# Lettura
print(profile["username"])       # 'alice' (KeyError se la chiave non esiste)
print(profile.get("phone"))      # None (nessun errore)
print(profile.get("phone", "n/a"))  # valore di default

# Scrittura/Aggiornamento
profile["email"] = "[email protected]"   # assegna/aggiorna
profile.update({"plan": "pro", "country": "IT"})

# Inserisci se assente e restituisci il valore
plan = profile.setdefault("plan", "free")  # non sovrascrive se già presente

# Rimozione
removed = profile.pop("country", None)  # rimuove e restituisce (o default)
# del profile["missing"]  # ❌ KeyError se non esiste
profile.popitem()  # rimuove l'ultima coppia (inserimento più recente)

💡 Suggerimento pratico: usa get quando una chiave potrebbe mancare; evita KeyError e rendi il codice più robusto.

Errore comune da evitare

Confondere in su chiavi e valori. L’espressione x in my_dict controlla le chiavi, non i valori: usa x in my_dict.values() per i valori.


🔁 Iterare su dizionari con for

Le dictionary views sono dinamiche: riflettono le modifiche al dizionario.

product = {"sku": "A-100", "price": 19.9, "stock": 12}

# Solo chiavi (default)
for k in product:
    print(k)

# Chiavi, valori, coppie
for k in product.keys():
    print("Key:", k)
for v in product.values():
    print("Value:", v)
for k, v in product.items():
    print(k, "→", v)

✨ Usa items() quando ti servono chiave e valore insieme; è più leggibile di accedere con product[k] dentro il ciclo.

Extra utili:

  • Filtrare/trasformare con dict comprehension: {k: v*1.1 for k, v in prices.items() if v < 20}.
  • Ordinare per valore: sorted(product.items(), key=lambda kv: kv[1]) (ritorna lista di tuple).

Domanda per te: perché sorted(d) ordina le chiavi e non gli elementi (chiave, valore)?


🧰 Metodi utili

  • get(key, default=None) → lettura sicura.
  • setdefault(key, default) → inserisce default se assente e ritorna il valore.
  • update([other], **kwargs) → unisce/aggiorna da altri dict/iterabili.
  • pop(key[, default]), popitem() → rimozioni.
  • keys(), values(), items()views dinamiche.
  • clear(), copy() (shallow).
  • fromkeys(iterable, value) → crea nuovo dict con chiavi date e stesso valore.
  • Comprehension: {k: f(v) for k, v in d.items()} per costruire in modo espressivo.

🔍 Copia profonda: per clonare strutture annidate usa import copy; deep = copy.deepcopy(d).


🧩 Esempi pratici

1) Rubrica con aggiornamento condizionato

contacts = {
    "alice": {"email": "[email protected]", "phone": "111"},
    "bob":   {"email": "[email protected]"}
}
name = "bob"
phone = contacts[name].get("phone") or "000"
contacts[name]["phone"] = phone
print("Bob phone:", contacts[name]["phone"])  # Bob phone: 000

2) Prezzi: aumento del 10% sotto una soglia

prices = {"pen": 1.0, "notebook": 2.5, "bag": 25.0}
adjusted = {k: (v*1.1 if v < 10 else v) for k, v in prices.items()}
print(adjusted)

3) Statistica parole (nota: per conteggio serio vedi collections.Counter)

text = "to be or not to be"
counts = {}
for w in text.split():
    counts[w] = counts.get(w, 0) + 1
print(counts)  # {'to': 2, 'be': 2, 'or': 1, 'not': 1}

🧠 Rifletti: in quali casi preferiresti setdefault rispetto a get(...)+assegnazione?


⚠️ Errore comune da evitare

  • KeyError: usare d[chiave] quando la chiave può mancare.
    Soluzione: d.get(chiave, default), if chiave in d:, oppure setdefault per inserire un default e continuare.
  • Shallow copy: copy() o dict(d) copiano solo il primo livello; se modifichi una lista interna, tocchi anche l’originale.
  • Confondere ordine con indicizzazione: i dict preservano l’ordine ma non sono indicizzabili con numeri (d[0] ❌).

📖 Sezione teorica

  • Dizionari: mapping chiave→valore, chiavi hashable, valori di qualunque tipo.
  • Accesso/Aggiornamento: [], get, update, setdefault, pop, del.
  • Iterazione: for k in d, for v in d.values(), for k, v in d.items(); views dinamiche.
  • Ordine: i dict preservano l’ordine di inserimento; non usano indici numerici.
  • Comprehension: costruisci/trasforma dict in una riga in modo leggibile.

📚 Glossario tecnico

  • Mapping: collezione che mappa chiavi a valori (es. dict).
  • Hashable: oggetto con __hash__ stabile; può essere chiave in un dict.
  • Dictionary view: oggetto dinamico restituito da keys/values/items.

📝 Esercizio finale

Costruisci un catalogo prodotti come dizionario e implementa le operazioni sotto.
Dati iniziali:

catalog = {
    "A100": {"name": "Mouse", "price": 12.5, "tags": ["usb", "peripheral"]},
    "B200": {"name": "Keyboard", "price": 29.0, "tags": ["usb"]},
}

Requisiti:

  1. Aggiungi un nuovo prodotto C300 usando update.
  2. Se un prodotto non ha il campo stock, aggiungilo a 0 con setdefault.
  3. Aumenta il prezzo del 10% per gli articoli sotto i 15 usando una dict comprehension.
  4. Stampa un report in inglese con sku, name, price formattato a 2 decimali.
  5. Rimuovi in sicurezza (pop(key, None)) un codice assente, senza errori.
  6. Extra: ordina il report per prezzo crescente usando sorted(catalog.items(), key=lambda kv: kv[1]["price"]).

Schema d’aiuto:

# Your code here...
for sku, data in catalog.items():
    print(f"{sku} → {data['name']} - ${data['price']:.2f}")

🧠 Quiz finale

Non guardare le risposte subito! Sono più sotto 👇

  1. Cosa garantiscono le chiavi di un dict?
    A) Devono essere mutabili
    B) Devono essere uniche e hashable
    C) Possono essere liste
  2. Cosa fa d.get("x", 0) se "x" non esiste?
    A) Lancia KeyError
    B) Restituisce None
    C) Restituisce 0
  3. Qual è il modo predefinito di iterare un dict?
    A) Su chiavi
    B) Su valori
    C) Su coppie (k, v)
  4. Quale istruzione inserisce se assente e restituisce il valore inserito?
    A) get
    B) setdefault
    C) update
  5. Qual è la complessità media di k in d?
    A) O(n)
    B) O(1)
    C) O(log n)
  6. I dict sono:
    A) Disordinati, indicizzati da interi
    B) Ordinati per inserimento, indicizzati da chiavi
    C) Strutture non modificabili
  7. Cosa fa popitem()?
    A) Rimuove la prima coppia inserita
    B) Rimuove l’ultima coppia inserita
    C) Rimuove una coppia a caso
  8. Quale codice evita KeyError?
    A) value = d["k"]
    B) value = d.get("k")
    C) del d["k"]

❓ FAQ

1) I dizionari preservano l’ordine?
Sì: preservano l’ordine di inserimento. Utile per report e serializzazioni prevedibili. Ricorda però che non sono indicizzabili per posizione.

2) dict o list di tuple (k, v)?
dict per look‑up rapido e aggiornamenti per chiave; lista di tuple per ordine personalizzato o duplicati.

3) Quando conviene Counter invece di un dict?
Quando devi contare occorrenze con API già pronte (most_common, somma, sottrazione…).

4) popitem() è LIFO?
Sì: rimuove l’ultima coppia inserita (coerente con l’ordine).

5) Come clono un dict annidato senza condividere riferimenti?
Usa copy.deepcopy().



Esterni
Python Tutorial – Strutture dati (dizionari)https://docs.python.org/3/tutorial/datastructures.html
Built‑in Types – Mapping Types dicthttps://docs.python.org/3/library/stdtypes.html
Real Python – Dictionaries in Pythonhttps://realpython.com/python-dicts/

SapereSemplice
• Lezione 2 – Primo script Python → https://www.saperesemplice.com/primo-script-python-hello/
• Lezione 3 – Variabili e Tipi di Dato → https://www.saperesemplice.com/variabili-tipi-dato-python/
• Lezione 9 – Ciclo for e range()https://www.saperesemplice.com/ciclo-for-range-python/
• Lezione 8 – Ciclo whilehttps://www.saperesemplice.com/ciclo-while-python-base/


🔁 Collegamento alla lezione successiva

➡️ Prosegui alla Lezione 13: Definire funzioni con def
(Il link verrà inserito non appena l’articolo sarà online.)

🗨️ Hai dubbi? Lascia un commento!
📩 Vuoi il PDF della lezione? Scrivici!
🔗 Condividi con un compagno di corso.


🧪 Risposte del quiz

  1. B
  2. C
  3. A
  4. B
  5. B
  6. B
  7. B
  8. B

📅 Aggiornato il 02/09/2025

Lascia un commento