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 Dato → https://www.saperesemplice.com/variabili-tipi-dato-python/
• Lezione 8 – Ciclowhile→ https://www.saperesemplice.com/ciclo-while-python-base/
• Lezione 9 – Cicloforerange()→ https://www.saperesemplice.com/ciclo-for-range-python/
Dettagli lezione
⏱️ Tempo stimato: 35–45 minuti
🧩 Difficoltà: Facile
🎯 Obiettivi specifici
- Creare dizionari con letterali
{}e costruttoredict(). - Accedere/aggiornare valori con
[],get,update,setdefault; rimuovere condel,pop,popitem,clear. - Iterare con
forsu 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,tupledi 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
getquando una chiave potrebbe mancare; evitaKeyErrore rendi il codice più robusto.
Errore comune da evitare
Confondere
insu chiavi e valori. L’espressionex in my_dictcontrolla le chiavi, non i valori: usax 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 conproduct[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
setdefaultrispetto aget(...)+assegnazione?
⚠️ Errore comune da evitare
- KeyError: usare
d[chiave]quando la chiave può mancare.
Soluzione:d.get(chiave, default),if chiave in d:, oppuresetdefaultper inserire un default e continuare. - Shallow copy:
copy()odict(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:
- Aggiungi un nuovo prodotto
C300usandoupdate. - Se un prodotto non ha il campo
stock, aggiungilo a0consetdefault. - Aumenta il prezzo del 10% per gli articoli sotto i 15 usando una dict comprehension.
- Stampa un report in inglese con
sku,name,priceformattato a 2 decimali. - Rimuovi in sicurezza (
pop(key, None)) un codice assente, senza errori. - 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 👇
- Cosa garantiscono le chiavi di un dict?
A) Devono essere mutabili
B) Devono essere uniche e hashable
C) Possono essere liste - Cosa fa
d.get("x", 0)se"x"non esiste?
A) LanciaKeyError
B) RestituisceNone
C) Restituisce 0 - Qual è il modo predefinito di iterare un dict?
A) Su chiavi
B) Su valori
C) Su coppie(k, v) - Quale istruzione inserisce se assente e restituisce il valore inserito?
A)get
B)setdefault
C)update - Qual è la complessità media di
k in d?
A) O(n)
B) O(1)
C) O(log n) - I dict sono:
A) Disordinati, indicizzati da interi
B) Ordinati per inserimento, indicizzati da chiavi
C) Strutture non modificabili - Cosa fa
popitem()?
A) Rimuove la prima coppia inserita
B) Rimuove l’ultima coppia inserita
C) Rimuove una coppia a caso - 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().
🔗 Link utili
Esterni
• Python Tutorial – Strutture dati (dizionari) → https://docs.python.org/3/tutorial/datastructures.html
• Built‑in Types – Mapping Types dict → https://docs.python.org/3/library/stdtypes.html
• Real Python – Dictionaries in Python → https://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 while → https://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
- B
- C
- A
- B
- B
- B
- B
- B
