Software in pratica

 ☗   ◀   ☰   ▶ 

LISTE E TABELLE

Parliamo ora di liste. Iniziamo col dire che una lista (che in Python ha superficialmente una vaga somiglianza con gli array o vettori o schiere di altri linguaggi) può essere pensata come una sequenza ordinata di elementi, a cui ci si può riferire attraverso un indice numerico che li contraddistingue all'interno della lista.

Ogni elemento di una lista si può riferire a qualsiasi tipo di dato, la lista è quindi una struttura dati, e può servire ad esempio per "contenere" un elenco di nomi, una serie di numeri o anche altre liste.

Normalmente per essere utilizzabile anche una lista va assegnata ad un nome di variabile, in modo da potersi riferire ad essa tramite quel nome (ricordo che un nome di variabile in Python serve a identificare qualsiasi cosa utilizzata nel programma).

Ecco come definire una lista:
a = []                                     # lista vuota
a = [12, 44, "F", "STRINGA", 0.0177, ""]   # lista con 6 elementi
a = [0] * 100                              # lista di 100 numeri 0

Ricordando che il primo elemento di una lista ha indice zero, potete riferirvi ai singoli elementi con la sintassi nomelista[indice], e potete usare gli elementi di una lista in ogni espressione o assegnamento in cui si può usare una normale variabile.

Per esempio, l'espressione
valori[4]
identifica l'elemento numero 4 (il quinto) della lista chiamata valori, mentre
valori[0]
si riferisce al primo elemento della lista.

Abbiamo detto che qualsiasi elemento di una lista può essere utilizzato ovunque si può utilizzare una variabile. Ad esempio è possibile assegnare il dato a cui si riferisce un elemento della lista a un'altra variabile con la seguente assegnazione

b = valori[40]

Questa riga prende il dato a cui si riferisce valori[40] e lo assegna alla variabile 'b'. Più in generale, se 'i' è una variabile che si riferisce ad un numero intero, l'assegnamento

b = valori[i]

assegna alla variabile 'b' il dato a cui si riferisce l'elemento numero 'i' della lista 'valori'. Cioè se 'i' si riferisce al numero 6, il valore a cui si riferisce valori[6] viene assegnato a 'b'.

Allo stesso modo un dato può essere assegnato a un elemento di una lista specificando semplicemente l'elemento della lista a sinistra del segno uguale:

valori[100] = 12
Il numero 12 viene assegnato all'elemento 100 della lista 'valori', mentre l'assegnazione:
valori[i] = b
assegna all'elemento valori[i] il dato a cui si riferisce la variabile 'b'.

Qual è l'utilità di tutto questo? Solitamente le liste si utilizzano assieme ai cicli per poterne scandire in modo automatico tutti gli elementi. Pensiamo ad esempio di voler simulare il lancio di tre dadi per mille volte, e annotarci quante volte la loro somma vale 3, quante volte 4 e così via fino a quante volte 18 (cioè sono usciti tre sei). Potremmo sicuramente usare sedici variabili chiamate tre, quattro, cinque ecc, e ad ogni lancio aggiungere 1 a quella desiderata. Dovremmo quindi scrivere una lunga serie di istruzioni if come queste:

if lancio == 3: 
    tre = tre + 1
if lancio == 4: 
    quattro = quattro + 1
......

Usando una lista possiamo invece usare una sola variabile che si riferisce alla lista, e incrementare i numeri a cui si riferiscono i singoli elementi della lista usando direttamente il valore ottenuto dal lancio come indice:

#------ PROGRAMMA SIMULAZIONE LANCI

import random

#---------------------------------------------------------------------

def lancio_dadi():   # Lancia tre dadi
    d1 = random.randint(1, 6)
    d2 = random.randint(1, 6)
    d3 = random.randint(1, 6)
    return d1 + d2 + d3

#---------------------------------------------------------------------

lista = [ 0 ] * 19
i = 1
while i <= 1000:
    lancio = lancio_dadi()
    lista[lancio] = lista[lancio] + 1
    i = i + 1
i = 3
while i <= 18:
    print("Il numero", i, "e' uscito", lista[i], "volte.")
    i = i + 1
Risultato (i valori ovviamente cambiano ad ogni esecuzione, ma in media mantengono queste grandezze):
Il numero 3 e' uscito 5 volte.
Il numero 4 e' uscito 15 volte.
Il numero 5 e' uscito 28 volte.
Il numero 6 e' uscito 45 volte.
Il numero 7 e' uscito 76 volte.
Il numero 8 e' uscito 86 volte.
Il numero 9 e' uscito 120 volte.
Il numero 10 e' uscito 126 volte.
Il numero 11 e' uscito 139 volte.
Il numero 12 e' uscito 126 volte.
Il numero 13 e' uscito 96 volte.
Il numero 14 e' uscito 66 volte.
Il numero 15 e' uscito 37 volte.
Il numero 16 e' uscito 25 volte.
Il numero 17 e' uscito 9 volte.
Il numero 18 e' uscito 1 volte.

Come potete vedere il programma risulta più compatto rispetto ad una soluzione senza liste, e i valori a cui si riferiscono gli elementi sono rapidamente recuperabili in sequenza attraverso un indice.

In questo esempio abbiamo definito una lista di 19 numeri in modo da potervi accedere direttamente con indici da 0 a 18, lasciando inutilizzati i primi tre (da 0 a 2). Avremmo potuto usare una lista di esattamente 16 elementi (con indici da 0 a 15), ma avremmo dovuto sottrarre 3 al valore dei lanci per poterli usare come indici, e risommare 3 agli indici per stamparli.

Ecco una rappresentazione dei vari numeri a cui si riferiscono gli elementi della lista appena utilizzata:



APPEND

Ogni lista è dotata di molte funzioni interne (dette metodi) che si chiamano come tutte le altre funzioni, facendole però precedere dal nome della lista a cui appartengono seguito da un punto (la stessa notazione punto già incontrata parlando del modulo math). Ecco come potete aggiungere degli elementi alla fine di una lista (di nome 'a') tramite il suo metodo append:

a.append("NUOVA STRINGA")  # aggiunge una stringa
a.append(2.99792458E+8)    # aggiunge un numero float

Per non incorrere in segnalazioni di errore di indici fuori range dovete sempre ricordarvi che non si può accedere ad un elemento di una lista se non è stato prima creato, quindi una lista vuota va prima popolata con chiamate successive del metodo append, o, in alternativa, si crea la lista già inizializzata (preimpostata) con dei dati.

Per quanto riguarda gli indici va ricordato che una lista è una sequenza di elementi allo stesso modo in cui una stringa è una sequenza di caratteri, e le possibilità di sezionamento, indirizzamento, controllo lunghezza e concatenamento delle stringhe sono identiche anche per le liste, quindi almeno per queste cose, se avete ben compreso le funzioni di stringa, adesso potete vivere di rendita.


CICLO FOR

Benché il ciclo while permetta di effettuare qualsiasi tipo di elaborazione ciclica, vi sono dei compiti ripetitivi che capita di dover svolgere spesso, come iterare (scorrere) sui caratteri di una stringa o sugli elementi di una lista. Il ciclo for del Python è pensato proprio per questo e permette di scrivere molte meno righe di programma. Ecco subito un esempio:

lista = [12, 13, 14, 15, 16, 17]
for e in lista:
    print(e)
Risultato:
12
13
14
15
16
17    


Il ciclo for gestisce un indice interno totalmente automatico, e con esso prende uno alla volta i singoli elementi della sequenza (partendo dal primo a sinistra) assegnandoli alla variabile indicata. Ad ogni iterazione esegue le istruzioni in esso contenute che come sempre vanno scritte indentate. Anche un ciclo for può essere interrotto con l'istruzione break, che fa proseguire il programma con la prima riga utile esterna al ciclo.


RANGE

Utilissima è la funzione range che, posta in un ciclo for, simula una lista di numeri. Nel seguente esempio la funzione range si comporta infatti come una lista di numeri di valore compreso tra 0 e 9 che vengono via via assegnati alla variabile e:
for e in range(10):
    print("ITERAZIONE NUMERO", e + 1)
Risultato:
ITERAZIONE NUMERO 1
ITERAZIONE NUMERO 2
ITERAZIONE NUMERO 3
ITERAZIONE NUMERO 4
ITERAZIONE NUMERO 5
ITERAZIONE NUMERO 6
ITERAZIONE NUMERO 7
ITERAZIONE NUMERO 8
ITERAZIONE NUMERO 9
ITERAZIONE NUMERO 10

Usando il ciclo for e la funzione range, il precedente programma di simulazione lanci diventa ancora più compatto:

#------ PROGRAMMA SIMULAZIONE LANCI

import random

#---------------------------------------------------------------------

def lancio_dadi():   # Lancia tre dadi
    d1 = random.randint(1, 6)
    d2 = random.randint(1, 6)
    d3 = random.randint(1, 6)
    return d1 + d2 + d3

#---------------------------------------------------------------------

lista = [ 0 ] * 19
for i in range(1000):
    lancio = lancio_dadi()
    lista[lancio] = lista[lancio] + 1
for i in range(16):
    print("Il numero", i+3, "e' uscito", lista[i+3], "volte.")

TABELLE

A volte può servire organizzare i dati in una tabella composta da righe e colonne. In Python, nonostante non esista un modo specifico per definirla in modo diretto, si può comunque ottenere agevolmente con una lista di liste.
tabella = [  [ "gennaio",   31 ],
             [ "febbraio",  28 ],
             [ "marzo",     31 ],
             [ "aprile",    30 ],
             [ "maggio",    31 ],
             [ "giugno",    30 ],
             [ "luglio",    31 ],
             [ "agosto",    31 ],
             [ "settembre", 30 ],
             [ "ottobre",   31 ],
             [ "novembre",  30 ],
             [ "dicembre",  31 ]    ]

for i in range(12):
    print("I giorni di", tabella[i][0], "sono", tabella[i][1])
Risultato
I giorni di gennaio sono 31
I giorni di febbraio sono 28
I giorni di marzo sono 31
I giorni di aprile sono 30
I giorni di maggio sono 31
I giorni di giugno sono 30
I giorni di luglio sono 31
I giorni di agosto sono 31
I giorni di settembre sono 30
I giorni di ottobre sono 31
I giorni di novembre sono 30
I giorni di dicembre sono 31

La tabella si può pensare composta da 12 righe (con indice da 0 a 11) e 2 colonne (con indice da 0 a 1). Il primo indice si riferisce alla sottolista all'interno della lista principale (riga), il secondo all'elemento all'interno della sottolista (colonna).




Se per riempire automaticamente una lista basta un loop, per una tabella ne occorrono due nidificati. Ecco un programmino che crea una tabella di 10x10 elementi inizializzati a zero e li modifica con i valori delle tabelline che avete studiato a scuola (ricordate che gli indici partono da zero, per questo nel calcolo dei prodotti aggiungiamo 1).

#------ PROGRAMMA TABELLINE

RIGHE = 10
COLONNE = 10
tabe = []                      # crea lista principale
for h in range(RIGHE):         # aggiunge 10 sottoliste
    tabe.append([0]*COLONNE)   # ciascuna con 10 elementi

for riga in range(10):
    for colonna in range(10):
        tabe[riga][colonna] = (riga+1) * (colonna+1)
        print(tabe[riga][colonna], "\t", end="")
    print()

La stringa "\t" indica un carattere di tabulazione (codice ASCII 9) utile per incolonnare i risultati all'inizio di colonne larghe 8 caratteri ciascuna in cui si può immaginare suddivisa ogni riga.

Risultato:
1 	2 	3 	4 	5 	6 	7 	8 	9 	10 	
2 	4 	6 	8 	10 	12 	14 	16 	18 	20 	
3 	6 	9 	12 	15 	18 	21 	24 	27 	30 	
4 	8 	12 	16 	20 	24 	28 	32 	36 	40 	
5 	10 	15 	20 	25 	30 	35 	40 	45 	50 	
6 	12 	18 	24 	30 	36 	42 	48 	54 	60 	
7 	14 	21 	28 	35 	42 	49 	56 	63 	70 	
8 	16 	24 	32 	40 	48 	56 	64 	72 	80 	
9 	18 	27 	36 	45 	54 	63 	72 	81 	90 	
10 	20 	30 	40 	50 	60 	70 	80 	90 	100 
 ☗   ◀   ☰   ▶