gl/ripetizioni

Liste, tuple e dizionari in Python: esercizi svolti

Liste, tuple e dizionari in Python per il biennio: metodi, slicing, errori tipici e tre esercizi svolti con output verificato, prima della verifica.

di Gaetano Livornese

  • #informatica
  • #seconda superiore
  • #tecnico
  • #python
  • #liste
  • #dizionari

Metà ottobre 2026: nelle seconde degli istituti tecnici (e nei licei scienze applicate) a scuola avete finito variabili, if e cicli, e adesso l’insegnante di informatica passa alle strutture dati: liste, tuple, dizionari. La verifica arriva fra cinque e otto settimane, tra fine novembre e metà dicembre, e quasi sempre è un compito scritto in cui bisogna leggere del codice e prevederne l’output, oppure scrivere una piccola funzione a mano. Questo post lo scrivo adesso perché le liste si imparano bene solo scrivendole, e due mesi di tempo bastano per farlo con calma.

Se vi manca la base sui cicli, ripartite da programmazione in Python da zero e da diagrammi di flusso e pseudocodice. Qui do per scontato che for, while e if non vi spaventino.

Perché servono le strutture dati

Con le sole variabili, per tenere sei voti servono sei nomi: v1, v2, v3… e il giorno in cui i voti sono sessanta il programma è ingestibile. Una lista raccoglie i valori sotto un solo nome, in ordine, e permette di ripetere la stessa operazione su tutti con un ciclo. Il resto del capitolo è decidere quale contenitore usare, e quali trappole evitare.

Liste: indici, slicing, metodi

Una lista si scrive fra parentesi quadre. Gli indici partono da zero, e quelli negativi contano dalla fine.

voti = [6, 4, 8, 5, 9, 7]
print(voti[0])      # 6
print(voti[-1])     # 7
print(voti[1:4])    # [4, 8, 5]
print(voti[::2])    # [6, 8, 9]
print(len(voti))    # 6

Lo slicing voti[a:b] prende dall’indice a incluso fino a b escluso: è la regola che costa più punti, perché si dimentica che l’estremo destro non c’è. voti[1:4] ha tre elementi, non quattro. Il terzo numero è il passo: [::2] salta un elemento ogni volta.

I metodi che si usano di più:

  • append(x) aggiunge x in fondo;
  • insert(i, x) inserisce x alla posizione i, spostando gli altri;
  • remove(x) elimina la prima occorrenza del valore x;
  • pop() elimina e restituisce l’ultimo elemento, pop(i) quello in posizione i.
voti.append(10)
voti.insert(0, 3)
print(voti)         # [3, 6, 4, 8, 5, 9, 7, 10]
voti.remove(3)
ultimo = voti.pop()
print(ultimo, voti) # 10 [6, 4, 8, 5, 9, 7]

Notate la differenza fra remove (cerco per valore) e pop (cerco per posizione): confonderli è un classico da verifica.

Scorrere una lista e la comprehension semplice

Per scorrere una lista si usa for, senza bisogno degli indici:

somma = 0
for v in voti:
    somma += v
print(somma, somma / len(voti), max(voti))   # 39 6.5 9

Quando si costruisce una nuova lista filtrando o trasformando un’altra, Python offre la list comprehension, che è solo una scrittura compatta del ciclo con append:

insufficienti = [v for v in voti if v < 6]
print(insufficienti)   # [4, 5]

Si legge: “per ogni v in voti, se v è minore di 6, mettilo nella nuova lista”. Se all’inizio non vi viene naturale, scrivete prima il ciclo esteso e poi riducetelo: all’orale e allo scritto vanno bene entrambe.

Tuple: liste che non si modificano

Una tupla si scrive con le parentesi tonde e funziona come una lista, ma è immutabile: dopo averla creata non puoi cambiare, aggiungere o togliere elementi.

punto = (3, 5)
print(punto[0])     # 3
punto[0] = 1        # TypeError: 'tuple' object does not support item assignment

Si usano per dati che non devono cambiare per costruzione: coordinate, una data (giorno, mese, anno), il valore di ritorno di una funzione che dà due risultati. Se scrivete punto[0] = 1 il programma si ferma con un errore, ed è proprio lo scopo: l’immutabilità vi protegge da modifiche involontarie.

Dizionari: chiave e valore

Un dizionario associa a ogni chiave un valore, e si scrive fra graffe. Non si cerca per posizione ma per chiave.

d = {"a": 1}
print(d.get("z"))       # None
print(d.get("z", 0))    # 0
d["z"]                  # KeyError: 'z'

Accedere con d["z"] a una chiave che non esiste dà KeyError; d.get("z", 0) invece restituisce un valore di riserva, che qui è 0. Per scorrere tutto si usa items(), che restituisce le coppie chiave-valore:

for chiave, valore in d.items():
    print(chiave, valore)

Stringhe: cenni

Una stringa si comporta come una lista di caratteri, per l’indicizzazione e lo slicing, ma è immutabile come una tupla. Tutto quello che vale per le liste su indici e fette vale anche qui.

s = "python"
print(s[0], s[-1], s[1:4], s.upper(), len(s))   # p n yth PYTHON 6

Per il lavoro sulle stringhe e sui file, nel post dedicato (stringhe e file in Python) c’è il resto.

Quando usare cosa

StrutturaOrdineModificabileSi usa per
Listasìsìsequenze di valori che cambiano (voti, punteggi)
Tuplasìnodati fissi (coordinate, date)
Dizionarioper chiavesìassociare un nome a un valore (conteggi, rubriche)

Regola pratica: se ti serve “l’elemento numero 3” usa una lista; se ti serve “il valore associato a Mario” usa un dizionario.

Esercizio 1: statistiche su una lista

Testo. Data voti = [6, 4, 8, 5, 9, 7], calcolare la media e costruire la lista dei voti insufficienti (minori di 6).

Svolgimento. La somma dei sei numeri è , la media è . Il filtro lascia solo 4 e 5.

voti = [6, 4, 8, 5, 9, 7]
media = sum(voti) / len(voti)
insufficienti = [v for v in voti if v < 6]
print(media)           # 6.5
print(insufficienti)   # [4, 5]

Per esercitarvi sulla stessa logica con più voci, i problemi di cicli e array del terzo anno sono il passo naturale successivo, e per un ripasso del metodo di lavoro vedete la pagina di informatica.

Errori tipici con le liste

Qui si perdono i punti, e conviene guardarli uno per uno.

Indice fuori range. Una lista di tre elementi ha indici 0, 1, 2. Scrivere lista[3] dà IndexError: list index out of range. Quando un ciclo while o un for con range va oltre, controllate se avete usato <= al posto di <.

Modificare la lista mentre la scorri. È l’errore più subdolo, perché non dà alcun messaggio: il programma gira e dà un risultato sbagliato. Lo vediamo nell’esercizio 2.

Copia contro riferimento. b = a non copia la lista: dà alla stessa lista un secondo nome.

a = [1, 2, 3]
b = a
b.append(4)
print(a)        # [1, 2, 3, 4]   a è cambiata!
c = a.copy()
c.append(5)
print(a, c)     # [1, 2, 3, 4] [1, 2, 3, 4, 5]

Per avere una copia indipendente servono a.copy() oppure a[:].

KeyError. Accedere a una chiave assente con le parentesi quadre. Rimedio: get, oppure un if chiave in dizionario prima.

Esercizio 2: togliere i pari (e il bug che nessuno vede)

Testo. Data numeri = [2, 4, 6, 7, 8, 10], eliminare tutti i numeri pari.

Primo tentativo, sbagliato:

numeri = [2, 4, 6, 7, 8, 10]
for n in numeri:
    if n % 2 == 0:
        numeri.remove(n)
print(numeri)   # [4, 7, 10]

Ci si aspetta [7], invece compaiono 4 e 10. Il motivo: il for scorre la lista tenendo un indice interno. Alla prima iterazione n è 2 (indice 0), che viene rimosso; la lista diventa [4, 6, 7, 8, 10] e l’indice avanza a 1, quindi salta il 4 e arriva al 6. Ogni rimozione fa slittare gli elementi e il ciclo ne salta uno.

Soluzione corretta: non modificare la lista che scorri, ma costruirne una nuova.

numeri = [2, 4, 6, 7, 8, 10]
dispari = [n for n in numeri if n % 2 != 0]
print(dispari)   # [7]

Altrimenti si può scorrere una copia, con for n in numeri.copy():. In tutti e due i casi, la lista che il ciclo legge non cambia durante la lettura.

Esercizio 3: contare le parole con un dizionario

Testo. Data la frase "il gatto e il cane e il topo", contare quante volte compare ciascuna parola e stampare quelle che compaiono più di una volta.

Svolgimento. split() spezza la frase in una lista di parole. Per ognuna: se è già chiave del dizionario aumento il contatore, altrimenti la inserisco con valore 1.

frase = "il gatto e il cane e il topo"
freq = {}
for parola in frase.split():
    if parola in freq:
        freq[parola] += 1
    else:
        freq[parola] = 1
print(freq)
# {'il': 3, 'gatto': 1, 'e': 2, 'cane': 1, 'topo': 1}

for parola, n in freq.items():
    if n > 1:
        print(parola, n)
# il 3
# e 2

Con get si accorcia tutto il blocco if/else in una riga: freq[parola] = freq.get(parola, 0) + 1. Il risultato è identico; a un compito va benissimo la versione lunga, se la scrivete correttamente.

Questo schema (il dizionario come contatore) è uno dei più richiesti nelle verifiche, perché mette insieme ciclo, condizione e struttura dati. Imparatelo a memoria nella sua forma con if/else.

Errori che costano punti

  • Dimenticare che lo slicing esclude l’estremo destro.
  • Partire da 1 invece che da 0 con gli indici.
  • Confondere remove (valore) con pop (posizione), o append con insert.
  • Dimenticare i due punti, oppure l’indentazione, dopo for e if.
  • Scrivere b = a pensando di aver copiato.
  • Modificare una lista dentro il ciclo che la scorre.
  • Usare d[chiave] senza controllare che esista.
  • Nelle prove su carta, scrivere l’output senza seguire il codice riga per riga: la traccia a mano è sempre la strada sicura.

Come prepararsi nelle prossime settimane

  1. Settimana 1-2: scrivete a mano, su carta, tutti gli snippet di questo post e prevedete l’output prima di eseguirli. Poi eseguiteli e confrontate.
  2. Settimana 3-4: riscrivete da soli i tre esercizi senza guardare la soluzione. Cambiate i dati (altri voti, un’altra frase) e verificate di nuovo.
  3. Settimana 5: fate esercizi misti, per esempio “data una lista di nomi, costruisci un dizionario con la lunghezza di ciascuno”. Se uno schema vi blocca, tornate all’esempio base.
  4. Ogni volta che il codice dà un errore, leggete il messaggio: IndexError, KeyError, TypeError dicono già dove guardare.

Non servono ore al giorno: tre sedute da quaranta minuti a settimana, con il codice scritto a mano, valgono più di una rilettura di tutto il quaderno.

Se volete un confronto su un compito vero, o se un passaggio proprio non si sblocca, scrivetemi dalla pagina contatti: faccio volentieri una diagnosi gratuita sugli esercizi che vi hanno dato.

Continua a leggere

Vuoi applicare quello che hai letto?

Parliamone 30 minuti gratis: guardiamo insieme dove sei bloccato e ti dico onestamente come posso aiutarti.

Oppure scrivimi su WhatsApp.