- Home
- iThink
- Programmazione per Ragazzi
- Liste e dizionari in Python con esempi pratici
Liste e dizionari in Python con esempi pratici
Divento Programmatore — Capitolo 5: Liste e dizionari
Finora abbiamo gestito un valore per variabile. Nei giochi serve di più: inventari (10+ oggetti), high-score (lista ordinata), mappe (coordinate → contenuto). Servono collezioni.
Cosa imparerai
| Struttura | Ordinata? | Accesso | Uso tipico | | --- | --- | --- | --- | | Lista (list) | Sì | Indice numerico [] | Sequenze, code, pile, high-score | | Dizionario (dict) | No (da Py 3.7+ mantiene inserimento) | Chiave [] | Mapping, configurazioni, stato entità |
1. Liste: sequenze ordinate mutabili
Creazione di una lista
vuota = []
numeri = [1, 2, 3, 4, 5]
mista = [1, "ciao", 3.14, True, [1, 2]] # Qualsiasi tipo, anche liste
da_stringa = list("Python") # ['P', 'y', 't', 'h', 'o', 'n']
da_range = list(range(1, 6)) # [1, 2, 3, 4, 5]
Indexing (indici 0-based)
colori = ["rosso", "verde", "blu", "giallo"]
print(colori[0]) # rosso (primo)
print(colori[1]) # verde
print(colori[-1]) # giallo (ultimo)
print(colori[-2]) # blu (penultimo)
Errore: IndexError se indice fuori range.
Slicing: estrai sotto-liste
numeri = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
numeri[2:5] # [2, 3, 4] da 2 (incluso) a 5 (escluso)
numeri[:3] # [0, 1, 2] primi 3
numeri[5:] # [5, 6, 7, 8, 9] da 5 alla fine
numeri[:] # [0...9] copia completa
numeri[::2] # [0, 2, 4, 6, 8] step 2 (pari)
numeri[1::2] # [1, 3, 5, 7, 9] step 2 da 1 (dispari)
numeri[::-1] # [9...0] **inverso!**
Metodi principali (mutano la lista)
| Metodo | Esempio | Effetto | Restituisce | | -------- | --------- | --------- | ------------- | | append(x) | lst.append(9) | Aggiunge in fondo | None | | insert(i, x) | lst.insert(0, "primo") | Inserisce all'indice | None | | extend(iter) | lst.extend([7,8]) | Aggiunge elementi iterabile | None | | pop([i]) | x = lst.pop() / lst.pop(0) | Rimuove e restituisce (default ultimo) | Elemento rimosso | | remove(x) | lst.remove("a") | Rimuove prima occorrenza di x | None | | clear() | lst.clear() | Svuota tutto | None | | index(x) | i = lst.index("a") | Indice prima occorrenza | int | | count(x) | n = lst.count("a") | Quante volte appare x | int | | sort() | lst.sort() / lst.sort(reverse=True) | Ordina in place | None | | reverse() | lst.reverse() | Inverte in place | None | | copy() | nuova = lst.copy() | Copia superficiale | Nuova lista |
Attenzione:
sort()ereverse()modificano l'originale e restituisconoNone.# ERRORE COMUNE ordinata = lista.sort() # ordinata = None! # CORRETTO lista.sort() ordinata = sorted(lista) # sorted() restituisce NUOVA lista
Lista vs Stringa (entrambe sequenze)
s = "Python"
l = list(s) # ['P', 'y', 't', 'h', 'o', 'n']
"".join(l) # "Python" (ricostruisce stringa)
"-".join(l) # "P-y-t-h-o-n"
2. Dizionari: mapping chiave → valore
Creazione di un dizionario
vuoto = {}
giocatore = {
"nome": "Alex",
"livello": 5,
"classe": "Mago",
"punti_vita": 42,
"inventario": ["pozione", "bacchetta"]
}
da_coppie = dict(nome="Sam", eta=12) # {'nome': 'Sam', 'eta': 12}
Accesso e modifica
print(giocatore["nome"]) # Alex (KeyError se chiave manca)
print(giocatore.get("mana")) # None (nessun errore)
print(giocatore.get("mana", 0)) # 0 (default se manca)
giocatore["livello"] = 6 # Modifica
giocatore["mana"] = 100 # Aggiunge nuova chiave
del giocatore["classe"] # Rimuove chiave
Metodi principali
| Metodo | Esempio | Descrizione | | -------- | --------- | ------------- | | keys() | d.keys() | Vista chiavi (iterabile) | | values() | d.values() | Vista valori | | items() | d.items() | Vista coppie (chiave, valore) | | get(k, default) | d.get("x", 0) | Sicuro, con default | | setdefault(k, v) | d.setdefault("x", []) | Se manca, imposta e restituisce | | pop(k, default) | d.pop("x") | Rimuove e restituisce valore | | update(altro) | d1.update(d2) | Unisce (sovrascrive) | | copy() | d.copy() | Copia superficiale |
Iterazione
for chiave in giocatore:
print(chiave, giocatore[chiave])
for chiave, valore in giocatore.items():
print(f"{chiave}: {valore}")
# Solo valori
for v in giocatore.values():
print(v)
3. Nesting: strutture complesse
Lista di dizionari (es. inventario oggetti)
inventario = [
{"nome": "Spada", "tipo": "arma", "danno": 10, "quantita": 1},
{"nome": "Pozione", "tipo": "consumabile", "effetto": "cura", "quantita": 5},
{"nome": "Scudo", "tipo": "armatura", "difesa": 5, "quantita": 1},
]
# Cerca arma
for oggetto in inventario:
if oggetto["tipo"] == "arma":
print(f"Arma equipaggiata: {oggetto['nome']} ({oggetto['danno']} dmg)")
Dizionario di liste (es. drop table per mostro)
drop_table = {
"Goblin": ["moneta", "pugnale", "straccio"],
"Drago": ["scaglia_drago", "oro", "spada_leggendaria"],
"Slime": ["gelatina", "gelatina", "pozione"],
}
mostro = "Drago"
print(f"Possibili drop da {mostro}: {drop_table[mostro]}")
Dizionario di dizionari (es. database giocatori)
database = {
"alex123": {"eta": 13, "punteggio": 1500, "vip": True},
"luna_gamer": {"eta": 12, "punteggio": 2100, "vip": False},
}
# Aggiorna punteggio
def aggiorna_punteggio(db, username, punti):
if username in db:
db[username]["punteggio"] += punti
else:
print("Utente non trovato")
aggiorna_punteggio(database, "alex123", 100)
4. Loop su collezioni: pattern comuni
Filtrare (list comprehension - anticipazione)
numeri = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
pari = [n for n in numeri if n % 2 == 0] # [2, 4, 6, 8, 10]
quadrati = [n**2 for n in numeri] # [1, 4, 9, 16, 25, 36, 49, 64, 81, 100]
Con indice: enumerate()
armi = ["Spada", "Arco", "Bastone"]
for i, arma in enumerate(armi, start=1):
print(f"{i}. {arma}")
# 1. Spada
# 2. Arco
# 3. Bastone
Più liste insieme: zip()
nomi = ["Guerriero", "Mago", "Ladro"]
vite = [100, 60, 80]
mana = [0, 100, 20]
for n, v, m in zip(nomi, vite, mana):
print(f"{n}: HP={v} MP={m}")
5. Copia: superficiale vs profonda
import copy
originale = [[1, 2], [3, 4]]
superficiale = originale.copy() # o list(originale) / originale[:]
profonda = copy.deepcopy(originale)
originale[0].append(99)
print(originale) # [[1, 2, 99], [3, 4]]
print(superficiale) # [[1, 2, 99], [3, 4]] ← CONDIVIDE liste interne!
print(profonda) # [[1, 2], [3, 4]] ← Indipendente
Regola: Se la lista/dizionario contiene altre liste/dizionari → usa copy.deepcopy().
6. Script completo: Sistema Inventario RPG
# inventario_rpg.py
"""Sistema inventario: aggiungi, rimuovi, usa, mostra, cerca."""
INVENTARIO_MAX = 20
class Inventario:
def __init__(self):
self.slot = [] # Lista di dict: {"nome": str, "tipo": str, "qta": int}
def aggiungi(self, nome: str, tipo: str, qta: int = 1) -> bool:
# Cerca se già presente (stackable)
for item in self.slot:
if item["nome"] == nome and item["tipo"] == tipo:
item["qta"] += qta
print(f"📦 {nome} x{qta} aggiunto (totale: {item['qta']})")
return True
# Nuovo slot
if len(self.slot) >= INVENTARIO_MAX:
print("❌ Inventario pieno!")
return False
self.slot.append({"nome": nome, "tipo": tipo, "qta": qta})
print(f"✨ Nuovo oggetto: {nome} x{qta}")
return True
def rimuovi(self, nome: str, qta: int = 1) -> bool:
for item in self.slot:
if item["nome"] == nome:
if item["qta"] <= qta:
self.slot.remove(item)
print(f"🗑️ {nome} rimosso completamente")
else:
item["qta"] -= qta
print(f"🗑️ {nome} -{qta} (rimasti: {item['qta']})")
return True
print(f"❌ {nome} non trovato")
return False
def usa(self, nome: str) -> bool:
for item in self.slot:
if item["nome"] == nome:
if item["tipo"] == "consumabile":
print(f"💊 Usi {nome}! Effetto applicato.")
return self.rimuovi(nome, 1)
else:
print(f"❌ {nome} non è consumabile")
return False
print(f"❌ {nome} non in inventario")
return False
def mostra(self):
print("\n=== INVENTARIO ===")
if not self.slot:
print(" (vuoto)")
else:
for i, item in enumerate(self.slot, 1):
print(f" {i}. {item['nome']} ({item['tipo']}) x{item['qta']}")
print(f" Slot: {len(self.slot)}/{INVENTARIO_MAX}")
def cerca_tipo(self, tipo: str) -> list:
return [item for item in self.slot if item["tipo"] == tipo]
# Demo
if __name__ == "__main__":
inv = Inventario()
inv.aggiungi("Spada ferro", "arma", 1)
inv.aggiungi("Pozione cura", "consumabile", 3)
inv.aggiungi("Pozione cura", "consumabile", 2) # Stack
inv.aggiungi("Scudo legno", "armatura", 1)
inv.mostra()
inv.usa("Pozione cura")
inv.mostra()
print("\nArmi:", inv.cerca_tipo("arma"))
print("Consumabili:", inv.cerca_tipo("consumabile"))
7. Tabella riassuntiva: quando usare lista vs dizionario
| Situazione | Struttura | Motivo | | ------------ | ----------- | -------- | | Sequenza ordinata (passi, livelli, log) | list | Indice ha significato | | Accesso per posizione (primo, ultimo, 5°) | list | lst[0], lst[-1] | | Mapping chiave→valore (config, stats, DB) | dict | d["chiave"] O(1) | | Chiavi uniche, lookup veloce | dict | Hash table | | Devi mantenere ordine inserimento | list o dict (Py 3.7+) | dict ora ordinato | | Contare occorrenze | dict o Counter | d[x] = d.get(x,0)+1 | | Pila (LIFO) / Coda (FIFO) | list / collections.deque | append/pop / popleft |
8. Esercizi pratici
- High-score: Lista di dizionari
{"nome": "", "punteggio": 0}. Funzioni:aggiungi_punteggio(),top_10(),salva_carica()(JSON - anticipazione) - Inventario completo: Estendi la classe sopra con: equipaggia, vendi, ordina per tipo/valore
- Rubrica: Dizionario
nome -> {"telefono": "", "email": "", "compleanno": ""}. CRUD completo - Mappa 2D: Lista di liste
[[0,1,0],[1,1,1],[0,0,0]](0=vuoto, 1=muro). Funzioni:stampa_mappa(),muovi_giocatore() - Analisi testo: Conta frequenza parole in una frase → dizionario
parola -> conteggio
9. Checklist fine capitolo
- [ ] Crea liste e dizionari, accedi con
[]e.get() - [ ] Usi slicing
lst[start:stop:step]e indici negativi - [ ] Conosci metodi mutatori:
append,pop,remove,sort,extend - [ ] Iteri con
for x in lst,for k, v in d.items(),enumerate(),zip() - [ ] Gestisci nesting: lista di dict, dict di liste, dict di dict
- [ ] Capisci copia superficiale vs
deepcopy()
Prossimo capitolo
Capitolo 6: Moduli e librerie standard — import, random, time, math: usa il codice degli altri. Creare propri moduli, __name__ == "__main__", librerie esterne con pip.
Serie "Divento Programmatore: Python e i Giochi" (Cervello Elettronico Vol.2). Codice completo, tabelle, esercizi. Target 10-14 anni + guide adulti.
Per approfondire
- Calcolatrice parlante in Python con le funzioni
- Il gioco dell'impiccato in Python
- Funzioni in Python: scriverle, chiamarle, riusarle
- Corsi e percorsi di programmazione