Liste

Come trattare sequenze modificabili di oggetti vari.

Supponiamo che un sistema di sorveglianza, attraverso di sensori tenga sotto controllo 6 porte. Vogliamo memorizzare in 6 variabili lo stato delle porte. Ma questa soluzione si dimostra poco flessibile. Possiamo anche raggruppare in un’unica variabile lo stato di tutte le porte. Potremmo usare una tupla come visto nel capitolo precedente, ma vogliamo anche che quando il programma si accorge che una porta è stata aperta o chiusa, modifichi il suo stato nella variabile. Le tuple sono delle sequenze immutabili quindi non sono adatte come soluzione di questo problema. Le tuple, una volta create, non possono essere modificate. In questo caso dobbiamo usare un oggetto lista. Se inizialmente tutte le porte sono chiuse avremo:

>>> porte = ['c', 'c', 'c', 'c', 'c', 'c']
>>> print(porte)
['c', 'c', 'c', 'c', 'c', 'c']

Possiamo cambiare lo stato di una porta, ad esempio la prima:

>>> porte[0] = 'a'
>>> print(porte)
['a', 'c', 'c', 'c', 'c', 'c']

Il comando precedente può essere interpretato come: “la porta di posizione 0” è stata aperta. In modo analogo possiamo aprire un’altra porta o chiuderne una:

>>> porte[3] = 'a'
>>> print(porte)
['a', 'c', 'c', 'a', 'c', 'c']
>>> porte[0] = 'c'
>>> print(porte)
['c', 'c', 'c', 'a', 'c', 'c']

SON QUI SON QUI SON QUI

Separare i dati dalle espressioni o dagli algoritmi che li usano è uno dei metodi fondamentali dell’informatica. Questo consente di accedere agli stessi dati in momenti diversi e per scopi (operazioni o programmi) diversi. Oppure consente di di utilizzare gli stessi programmi su dati diversi. Nei linguaggi di programmazione, di solito, un nome che fa riferimento ad un valore viene detto “variabile”, perché il nome, in momenti diversi, può fare riferimento a valori diversi. Le variabili in Python sono dunque degli identificatori collegati con oggetti. Alcuni tipi di oggetti li abbiamo già incontrati: numeri interi (int), numeri in virgola mobile (float), stringhe (str). Ce ne sono altri che impareremo a usare più avanti: liste (list), tuple (tuple), dizionari (dict), ... in realtà ogni cosa in Python è un oggetto.

Vediamo comunque subito un primo banale uso delle liste:

>>> omo=["Mario Rossi", 45, "via Verdi, 4"]
>>> print("Sig.", omo[0], "\nabitante in", omo[2], "\ndi anni", omo[1])
Sig. Mario Rossi
abitante in via Verdi, 4
di anni 45

Alcune osservazioni:

  1. Una lista può contenere oggetti diversi, anche altre liste. Nel caso precedente, il primo e l’ultimo elemento della lista sono stringhe il secondo è un numero intero.
  2. Si possono estrarre gli elementi di una lista usando gli indici con la sintassi: <lista>[<indice>]
  3. È Importante ricordare che le liste partono dall’elemento 0, cioè il primo elemento di una lista ha sempre indice 0, il secondo ha indice 1 e così via.
  4. Possiamo anche estrarre gli elementi riferendoci alla fine della lista: l’ultimo elemento ha indice -1, il penultimo -2 e così via.

Python mette a disposizione strumenti per trattare sequenze di oggetti qualsiasi in modo analogo a come tratta le stringhe che sono sequenze di caratteri. Gli oggetti liste e le tuple sono sequenze ordinate di altri oggetti che possono essere numeri, stringhe o anche liste o tuple. Una lista può essere costruita ponendo gli oggetti, separati da virgole, tra una coppia di parentesi quadre. Una tupla è costruita ponendo gli oggetti, sempre separati da virgole, tra una coppia di parentesi tonde. Esempi:

>>> lista=[3, "pippo", ["sotto", "lista"], 3.14]
>>> tupla=(["multipli", "di", 7], 0, 7, 14, "ecc")
>>> print len(lista)
4
>>> print len(tupla)
5

Alla parola lista è associata una lista di 4 elementi: un intero, una stringa, una lista e un numero in virgola mobile. Alla parola tupla è associata una tupla di 5 elementi: una lista, 3 interi e una stringa.

Tutto quello che abbiamo detto sulle stringhe come sequenze, i metodi per estrarre elementi o fette, vale anche per le liste e per le tuple. Ad es. se voglio estrarre l’ultimo elemento da lista e i tre interi da tupla posso scrivere:

>>> print lista[-1]
3.14
>>> print tupla[1:4]
(0, 7, 14)

Bisogna ricordare che in tutte le sequenze l’indice parte da 0. Liste e tuple sono molto simili tra di loro, la differenza è piuttosto tecnica: le liste sono oggetti modificabili mentre le tuple, come le stringhe, una volta create, non possono essere modificate. Le operazioni che modificano l’oggetto possono essere compiute sulle liste ma non su stringhe e tuple. Nelle liste è possibile eliminare un elemento o inserirlo in un certo punto:

>>> del lista[1]
>>> print lista
[3, ['sotto', 'lista'], 3.1400000000000001]
>>> lista.insert(2, "Mario")
>>> print lista
[3, ['sotto', 'lista'], 'Mario', 3.1400000000000001]

Ma l’operazione che useremo più spesso sarà quella di costruire una lista. Si può partire da una lista vuota e aggiungere elementi alla fine. Ad esempio se voglio una lista di numeri quadrati incomincio assegnando alla parola quadrati una lista vuota e poi, in un ciclo, con il metodo append aggiungo alla lista quanti quadrati voglio:

>>> quadrati=[]
>>> for num in range(10): quadrati.append(num*num)

>>> print quadrati
[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]

C’è anche un altro modo per ottenere lo stesso risultato usando la sintassi della costruzione di liste. Ad esempio se voglio una lista con i primi 10 numeri cubi posso usare un meccanismo analogo al precedente, ma con una scrittura più sintetica:

>>> cubi=[num*num*num for num in range(10)]
>>> print cubi
[0, 1, 8, 27, 64, 125, 216, 343, 512, 729]

Scriviamo un programma che stampi alcuni dati statistici sui numeri contenuti in una lista. La somma degli elementi di una lista di numeri si può ottenere inizializzando a 0 una variabile e poi aggiungendo, a questa, ogni elemento della lista:

def somma(lista):
    """Somma gli elementi di una lista di numeri."""
    risultato=0
    for n in lista: risultato+=n
    return risultato

Realizzata la funzione somma, trovare la media è banale:

def media(lista):
    return somma(lista)/float(len(lista))

Si possono realizzare diverse altre funzioni statistiche e una procedura che riceva come parametro una lista e stampi i risultati delle funzioni statistiche che abbiamo creato:

def statistica(lista):
    print "La lista è: %s" % lista
    print "Media dei valori: %s" % media(lista)
    print "Valore minimo %s" % minimo(lista)

<F5> e poi nella shell di IDLE la proviamo:

>>> statistica([23, 65, 73, 13, 33, 95, 47, 83, 72])
La lista è: [23, 65, 73, 13, 33, 95, 47, 83, 72]
Media dei valori: 56.0
Valore minimo 13

Riassumendo

  • Le liste e le tuple sono contenitori di oggetti. L’indicizzazione e l’affettamento, che abbiamo visto per le stringhe, funzionano allo stesso modo per tutte le sequenze.

  • Le liste sono sequenze modificabili, le tuple no.

  • Il metodo append permette di aggiungere elementi alla fine delle liste. La sintassi è:

    <lista>.append(<oggetto>).
    
  • In Python esiste anche una sintassi particolare per costruire liste.

Prova tu

  1. Scrivi altre funzioni statistiche per liste di numeri: massimo, scarto quadratico medio, ...
  2. Integra queste nuove funzioni nella procedura statistica.
  3. Scrivi una funzione che stampi gli elementi di una lista uno sotto l’altro.
  4. Scrivi una funzione che, data una lista di numeri e un valore, stampi solo i numeri maggiori di quel valore.
  5. Scrivi una funzione che, data una lista di numeri e un valore, restituisca una lista formata solo dagli elementi della lista maggiori di quel valore.