Immaginiamo di dover programmare un software per gestire i voti di una classe scolastica. La
prima cosa che può venire in mente è di creare una variabile per ogni alunno. Siccome non sappiamo
in anticipo i nomi degli studenti e il loro numero, probabilmente scriveremo qualcosa tipo Studente1,
Studente2, Studente3
, ecc. Ora per ogni studente dovremo probabilmente creare la variabile
NomeStudente1, CognomeStudente1, VotiStudente1, AssenzeStudente1
ecc. In pratica il
programma conterrebbe un numero enorme di variabili e sarebbe difficilissimo gestirle.
Per questo tutti i linguaggi di programmazione consentono di aggregare molte variabili
in nuovi tipi di dati, che sono detti di solito tipi di dati derivati. I tipi di dati
visti finora (int, float, bool
) vengono detti tipi di dati atomici (o
elementari): un tipo di dato derivato è quindi un insieme di dati di tipo atomico (ma anche a loro volta
derivato) aggregati in un'unica variabile. A volte i dati componenti devono essere tutti dello stesso tipo (cioè
tutti numeri o tutte stringhe), a volte possono essere di tipi diversi.
Tornando al nostro esempio, potrei definire uno studente come un oggetto formato da un dato nome
(str
), un cognome
(str
), un dato assenze
, (int
)
e così via. Poi potrei definire una classe scolastica come un insieme di studenti, e così via. Certamente
dovrei avere delle istruzioni in grado di selezionare il dato (atomico) che voglio leggere o scrivere.
Così, se oggi ho interrogato il quinto studente della I A e gli ho messo 8, dovrei poter dire al linguaggio:
assegna al voto dello studente 5 della classe I A il valore 8.
Vediamo le istruzioni che ci mette a disposizione Python.
Una delle caratteristiche più potenti di Python è la presenza a livello nativo di un gran numero di tipi di dato derivati, e la semplicità della sintassi per manipolarli.
Il tipo di dato derivato più usato è senz'altro la lista (Inglese: list). Una lista è un insieme di dati (detti elementi) a cui è associato un ordine. Può contenere elementi di tipo diverso e può contenere anche più volte lo stesso elemento.
Per definire una lista si scrivono i suoi elementi, separati da virgole, tra parentesi quadre. Facciamo un po' di esempi direttamente in IDLE (al solito, potete omettere i commenti).
>>> citta = ["Roma", "Milano", "Firenze", "Bologna"] # una lista di 4 string >>> numeri = [1, 4, 5, 12, 23, 40] # una lista di 6 interi >>> mista = [1, "due", 3, "quattro"] # elementi di tipo diverso >>> numeri_uguali = [1, 4, 1, 6, 6, 4, 7, 7, 7, 1, 6] # elementi ripetuti >>> vuota = [] # lista vuota, senza elementi >>> citta
['Roma', 'Milano', 'Firenze', 'Bologna']
>>> numeri
[1, 4, 5, 12, 23, 40]
Notate che nella prima istruzione ho assegnato alla variabile città
un'intera lista formata da quattro
stringhe. Quando poi, più sotto, chiedo il valore della variabile citta
, IDLE mi risponde ristampando le
stringhe tra parentesi quadre. La cosa è simile per le altre liste.
Anche sulle liste possiamo compiere le operazioni di addizione e
moltiplicazione per un intero, come per le stringhe, ed usare la funzione type()
;
continuate in IDLE così:
>>> citta
['Roma', 'Milano', 'Firenze', 'Bologna']
>>> numeri
[1, 4, 5, 12, 23, 40]
>>> citta + numeri
['Roma', 'Milano', 'Firenze', 'Bologna', 1, 4, 5, 12, 23, 40]
>>> 2 * citta
['Roma', 'Milano', 'Firenze', 'Bologna', 'Roma', 'Milano', 'Firenze', 'Bologna']
>>> type(mista)
<class 'list'>
Dato che quando si definisce una lista capita spesso di dover scrivere righe di codice molto lunghe, Python permette di andare a capo liberamete tra gli elementi della lista. Attenti a non dimenticare le virgole: suggerisco, quando si va a capo, di scrivere sempre la virgola come ultimo carattere della riga superiore. IDLE ci fa capire che la riga successiva è una continuazione scrivendo i caratteri più a destra.
>>> lista_lunga = ["uno", 2, "tre", 4,
"cinque", 6, "sette",
8, "nove", 10]
Sugli oggetti di tipo lista possiamo applicare un gran numero di funzioni. La maggior parte di esse viene chiamata però non con la sintassi che già conosciamo, ma con una sintassi simile a quella che abbiamo già visto per i moduli.
Se nome_lista è una variabile di tipo lista, possiamo chiamare una funzione nome_funzione applicata ad essa con la sintassi:
nome_lista.nome_funzione(argomenti ...)
In questo modo il nome della lista a cui stiamo applicando la funzione non compare tra gli argomenti della funzione (cioè tra le parentesi), ma diventa una specie di parametro "speciale" che si scrive davanti al nome di funzione. Per conoscere tutte le funzioni di questo tipo possiamo digitare in IDLE:
>>> help(list)
Vediamo le più usate (nella tabella supponiamo che la variabile l
contenga una lista):
Funzione | Significato |
---|---|
l.append(a) |
Aggiunge l'elemento a alla fine della lista l |
l.insert(n, a) |
Aggiunge l'elemento a al posto n nella lista (i posti sono numerati da 0,
vedi sotto) |
l.remove(a) |
Rimuove dalla lista l l'elemento a . Se a non appartiene
alla lista provoca un ValueError |
l.sort() |
Ordina gli elementi della lista in ordine alfabetico o numerico |
l.reverse() |
Inverte l'ordine degli elementi della lista |
l.count(a) |
Restituisce (come int ) il numero di occorrenze di a nella lista (cioè
quante volte l'elemento a è contenuto in l , 0 se non
è presente) |
l.pop(a) |
Rimuove l'elemento a dalla lista e lo restituisce come risultato della funzione.
Usata senza parametro rimuove l'ultimo elemento |
l.clear() |
Elimina tutti gli elementi: la lista l diventa vuota |
citta
come
nell'esempio precedente. In IDLE date i seguenti comandi. Dopo ogni comando cercate di
immaginare come è cambiata la lista e controllate (nell'esercizio non è mostrato l'output di IDLE)>>> citta.append("Venezia")
>>> citta
>>> citta.remove("Roma")
>>> citta
>>> citta.insert(1, "Roma")
>>> citta
>>> citta.sort()
>>> citta
>>> citta.reverse()
>>> citta.count("Torino")
>>> citta.clear()
>>> citta
Altre funzioni devono invece essere chiamate con la sintassi che abbiamo già visto, inserendo la lista come parametro della funzione stessa.
Funzione | Significato |
---|---|
len(l) |
Restituisce (come int ) la lunghezza della lista, cioè il numero dei suoi elementi |
max(l) |
Restituisce l' elemento più grande dalla lista (in ordine alfabetico o numerico). Se gli oggetti non sono confrontabili (ad es. numeri e stringhe) da un TypeError |
min(l) |
Restituisce l'elemento più piccolo della lista |
sum(l) |
Restituisce la somma di tutti gli elementi della lista. Devono essere tutti numeri altrimenti da un TypeError |
E' un'altra situazione che può disorientare un principiante: alcune funzioni vanno chiamate in un modo, altre in un modo differente. Il motivo di tutto ciò è piuttosto oscuro, e di difficile comprensione per chi non abbia già una certa esperienza con i linguaggi di programmazione. Per il momento è utile cercare di fare molta pratica in modo da ricordare bene l'uso delle funzioni sulle liste e non confondersi sulla loro sintassi.
capitali
vuota"Roma", "Parigi", "Londra"
"Madrid"
(attenti! Qui non potete usare append())
"Roma"
"Parigi"
in fondo"Parigi"
è contenuta nella lista (dovrebbero essere 5)Come facciamo a leggere o scrivere un singolo elemento appartenente ad una lista? La cosa è semplice: ad ogni
elemento è associato un numero, detto indice, che corrisponde alla sua posizione
nella lista. Il primo elemento ha indice 0 (di nuovo questa tradizione deriva dal linguaggio C) quindi l'ultimo
ha indice uguale alla lunghezza della lista meno 1 (si può ottenere con la funzione len()
).
Per accedere ad un elemento si deve scrivere il nome della lista e subito dopo l'indice dell'elemento tra parentesi quadre, secondo la sintassi nome_lista[indice] sia in lettura che in scrittura. Proviamo ancora in IDLE:
>>> citta = ["Roma", "Milano", "Venezia", "Firenze", "Bologna"] >>> citta[4]
'Bologna'
>>> citta[2] = "Napoli" >>> citta
['Roma', 'Milano', 'Napoli', 'Firenze', 'Bologna']
>>> citta[0] + citta[1]
'RomaMilano'
Nella seconda riga ho letto il quinto elemento della lista citta
(che ha
indice 4); nella terza ho assegnato al terzo elemento il nuovo valore "Napoli"
,
nell'ultima ho fatto la somma del primo e secondo elemento (concatenando le stringhe).
La funzione index()
cerca un elemento nella lista e ci restituisce il suo
indice (o l'indice della sua prima occorrenza se è contenuto più volte). Se l'elemento non è presente ci da un
ValueError.
>>> citta.index("Roma")
0
>>> citta.index("Firenze")
3
>>> citta.index("Torino")
Traceback (most recent call last): File "<pyshell#3>", line 1, in <module> citta.index("Torino") ValueError: 'Torino' is not in list
E' molto facile confondersi usando gli indici. Ricordate sempre che il primo elemento ha indice 0, l'ennesimo elemento ha indice n - 1, l'ultimo len - 1. Se scriviamo un indice che non esiste otteniamo un nuovo tipo di errore: IndexError.
Infine possiamo utilizzare gli operatori booleani in
e not in
che ci
dicono se un elemento appartiene o no ad una lista.
>>> "Roma" in citta
True
>>> "Catanzaro" in citta
False
>>> "Milano" not in citta
False
>>> "Sassari" not in citta
True
>>> numeri = [1, 3, 5, 7, 9]
>>> numeri[0] = numeri[2]
>>> numeri[1] = numeri[3] + numeri[4]
>>> numeri.append(numeri[3])
>>> numeri[3] = sum(numeri)
>>> numeri[2] = numeri[0] * numeri[1]
>>> numeri.sort()
ESERCIZIO 11.4 Ora provate voi
numeri
con i primi 5 numeri pari (partendo da 2)SOLUZIONI>>> numeri
[8, 4, 12, 8, 18]
Ora proviamo ad usare quanto abbiamo imparato in un programma.
materie = ["Italiano", "Matematica", "Storia", "Geografia", "Inglese"]
voti = [ 8, 6, 5, 9, 8]
while
con una variabile contatore i
. La variabile
dovrà variare tra 0 e la lunghezza di materie
(non compresa).voti
. ATTENZIONE:
per calcolare la media è necessario dividere per il numero dei voti. Potreste essere tentati di
dividere per 5, ma dal punto di vista di un programmatore è meglio ricavare la lunghezza della
lista voti
mediante la funzione ... In questo modo, se dovessimo aggiungere o togliere
altre materie, non sarebbe necessario modificare il programma.Il tuo voto in Italiano e' 8
Il tuo voto in Matematica e' 6
Il tuo voto in Storia e' 5
Il tuo voto in Geografia e' 9
Il tuo voto in Inglese e' 8
La tua media e' 7.2
Il tuo voto piu' alto e' 9
Il tuo voto piu' basso e' 5
ESERCIZIO 11.6: Inseriamo noi i votivoti
deve essere inizialmente vuotawhile
simile a quello dell'esercizio
precedente. Nel corpo del ciclo chiedete in input all'utente il suo voto nell' i-esima materia
ed aggiungetelo in coda a voti
. Esempio di I/O (l'output del programma è stampato in blu
e le risposte dell'utente sono in nero):
Inserisci il tuo voto in Italiano 8
Inserisci il tuo voto in Matematica 8
. . .
ATTENZIONE: la funzione input()
, a differenza della print()
prende come
argomento una sola stringa, quindi dovete ottenere il prompt
concatenando più stringhe con il +
(e facendo attenzione agli spazi) ...m
voti
l'indice di m
e memorizzatelo in una variabile
ind
materie
c'è la materia in cui
avete preso quel voto, quindi potete stampare:
Il tuo voto piu' basso e' 5 in Matematica
Fine della lezione