2.8. Introduzione alle liste
Le liste sono, tra i tipi di dati in Python, la vera forza
motrice. Se la vostra sola esperienza con le liste sono gli
array in Visual Basic o (Dio ve ne scampi!) il datastore di
Powerbuilder, fatevi forza e osservate come si usano in
Python.
|
Una lista in Python è come un array in Perl.
In Perl, le variabili che contengono array hanno un nome che
inizia sempre con il carattere @; in
Python le variabili possono avere qualunque nome, è il
linguaggio che tiene traccia internamente del tipo di dato.
|
|
Una lista in Python è molto più di un array in Java
(sebbene possa essere usato allo stesso modo, se davvero
non volete altro). Un'analogia migliore sarebbe la classe
Vector, che può contenere oggetti
di tipo arbitrario e si espande automaticamente quando vi si
aggiungono nuovi elementi.
|
Esempio 2.15. Definire una lista
>>> li = ["a", "b", "mpilgrim", "z", "example"]
>>> li
['a', 'b', 'mpilgrim', 'z', 'example']
>>> li[0]
'a'
>>> li[4]
'example'
|
Per prima cosa definiamo una lista di 5 elementi. Notate che
questi mantengono l'ordine d'inserimento, in quanto una lista
e' un insieme ordinato di elementi racchiusi tra parentesi
quadrate.
|
|
A differenza di altri linguaggi, Python non permette di
scegliere se gli array cominciano con l'elemento 0 oppure 1.
Se la lista non è vuota, il primo elemento si indica sempre
con li[0].
|
|
In questa lista di 5 elementi, l'ultimo si indica con
li[4] perché le liste hanno sempre
base zero.
|
Esempio 2.16. Indici di liste negativi
>>> li
['a', 'b', 'mpilgrim', 'z', 'example']
>>> li[-1]
'example'
>>> li[-3]
'mpilgrim'
|
Un indice negativo accede agli elementi a partire dalla fine
della lista, contando all'indietro. L'ultimo elemento di una
lista non vuota è sempre li[-1].
|
|
Se gli indici negativi vi confondono, pensate in questo modo:
li[-n] == li[len(li) - n]. Così, in
questa lista, li[-3] == li[5 - 3] == li[2].
|
Esempio 2.17. Sezionare una lista.
>>> li
['a', 'b', 'mpilgrim', 'z', 'example']
>>> li[1:3]
['b', 'mpilgrim']
>>> li[1:-1]
['b', 'mpilgrim', 'z']
>>> li[0:3]
['a', 'b', 'mpilgrim']
|
Potete estrarre una sezione di una lista, chiamata
“slice”, (fetta), specificandone i due estremi.
Il valore della sezione è una nuova lista, contenente tutti
gli elementi, nello stesso ordine, dal primo indice (in questo
caso li[1]), fino al secondo indice escluso
(in questo caso li[3]).
|
|
Il sezionamento, o slicing, funziona anche se uno o entrambi
gli indici sono negativi. Potete pensarla in questo modo:
leggendo la lista da sinistra a destra, il primo indice
specifica il primo elemento che volete, mentre il secondo
specifica il primo elemento che non volete. Il valore
ritornato è una lista degli elementi che stanno in mezzo.
|
|
Gli elementi della lista si contano da zero, così
li[0:3] ritorna i primi tre elementi della
lista, partendo da li[0] fino a
li[3] escluso.
|
Esempio 2.18. Sezionamento abbreviato
>>> li
['a', 'b', 'mpilgrim', 'z', 'example']
>>> li[:3]
['a', 'b', 'mpilgrim']
>>> li[3:]
['z', 'example']
>>> li[:]
['a', 'b', 'mpilgrim', 'z', 'example']
|
Se l'indice di sinistra è 0, potete non indicarlo e lo 0 è
sottinteso. In questo caso li[:3] è
identico a li[0:3] dell'esempio
precedente.
|
|
Allo stesso modo, se l'indice destro è pari alla lunghezza
della lista, potete lasciarlo sottinteso. Così
li[3:] è identico a
li[3:5], perché la lista ha 5 elementi.
|
|
Notate la simmetria. In questa lista di 5 elementi,
li[:3] ritorna i primi 3, mentre
li[3:] ritorna gli ultimi 2 elementi.
Di fatto, li[:n] ritornerà sempre i primi
n elementi e li[n:]
ritornerà la parte restante della lista a prescindere
dalla lunghezza di quest'ultima.
|
|
Se chiedete un sezionamento senza specificare alcun indice, tutti
gli elementi della lista saranno inclusi. L'oggetto restituito
però non è la lista li originale; è una
nuova lista che contiene gli stessi elementi.
li[:] è un'abbreviazione per creare una
copia completa di una lista.
|
Esempio 2.19. Aggiungere elementi ad una lista
>>> li
['a', 'b', 'mpilgrim', 'z', 'example']
>>> li.append("new")
>>> li
['a', 'b', 'mpilgrim', 'z', 'example', 'new']
>>> li.insert(2, "new")
>>> li
['a', 'b', 'new', 'mpilgrim', 'z', 'example', 'new']
>>> li.extend(["two", "elements"])
>>> li
['a', 'b', 'new', 'mpilgrim', 'z', 'example', 'new', 'two', 'elements']
|
append aggiunge un
singolo elemento alla fine della lista.
|
|
insert inserisce un singolo elemento in
una posizione specifica della lista. L'argomento numerico è
l'indice del primo elemento che verrà spostato nella
posizione successiva. Notate che gli elementi di una lista
non devono necessariamente essere unici; adesso ci sono 2
elementi distinti con il valore 'new',
li[2] e li[6].
|
|
extend concatena due liste. Notate che non si può chiamare
extend con argomenti multipli: l'unico argomento accettato
è una lista. In questo caso la lista ha due elementi.
|
Esempio 2.20. Ricerca in una lista
>>> li
['a', 'b', 'new', 'mpilgrim', 'z', 'example', 'new', 'two', 'elements']
>>> li.index("example")
5
>>> li.index("new")
2
>>> li.index("c")
Traceback (innermost last):
File "<interactive input>", line 1, in ?
ValueError: list.index(x): x not in list
>>> "c" in li
0
|
index cerca la prima presenza di un
valore nella lista e ne ritorna l'indice.
|
|
index cerca la prima
presenza di un valore nella lista.
In questo caso, 'new' compare due volte
nella lista, in li[2] e
li[6], ma index
ritorna solamente il primo indice, 2.
|
|
Se il valore non è presente nella lista, Python solleva
un'eccezione. Questo comportamento è diverso dalla maggior
parte dei linguaggi, in cui viene ritornato qualche valore di
indice non valido. Per quanto il lancio di un'eccezione possa
sembrare seccante, in realtà è meglio così perché il vostro
programma vi indicherà la radice del problema, anziché bloccarsi
più tardi quando cercherete di usare l'indice non valido.
|
|
Per controllare se un valore è nella lista usate l'operatore
in, che ritorna 1 se il valore è
presente e 0 in caso contrario.
|
|
Prima della versione 2.2.1, Python non aveva un tipo di dato
booleano distinto dai numeri interi. Per compensare, Python
accettava quasi tutto in un contesto booleano (come un comando
if), secondo la seguente regola: 0 è falso; tutti gli
altri numeri sono veri. Una stringa vuota
("") è falsa; tutte le altre stringhe sono
vere. Una lista vuota ([]) è falsa; tutte
le altre liste sono vere. Una tupla vuota
(()) è falsa; tutte le altre tuple sono
vere. Un dizionario vuoto ({}) è falso;
tutti gli altri dizionari sono veri. Queste regole valgono
ancora in Python 2.2.1 e oltre, ma ora si può usare anche un
valore booleano vero e proprio, che ha valore
True o False.
Notate le maiuscole; questi valori, come tutto il resto in
Python, sono case-sensitive.
|
Esempio 2.21. Togliere elementi da una lista
>>> li
['a', 'b', 'new', 'mpilgrim', 'z', 'example', 'new', 'two', 'elements']
>>> li.remove("z")
>>> li
['a', 'b', 'new', 'mpilgrim', 'example', 'new', 'two', 'elements']
>>> li.remove("new")
>>> li
['a', 'b', 'mpilgrim', 'example', 'new', 'two', 'elements']
>>> li.remove("c")
Traceback (innermost last):
File "<interactive input>", line 1, in ?
ValueError: list.remove(x): x not in list
>>> li.pop()
'elements'
>>> li
['a', 'b', 'mpilgrim', 'example', 'new', 'two']
|
remove toglie la
prima presenza di un valore nella lista.
|
|
remove toglie solo la prima
ricorrenza di un valore specificato. In questo
caso, 'new' compare due volte nella
lista, ma li.remove("new") ha tolto solo
il primo elemento che ha trovato.
|
|
Se il valore non è presente nella lista, Python solleva
un'eccezione. Questo comportamento rispecchia quello del
metodo index.
|
|
pop è un animale interessante. Fa due
cose: toglie l'ultimo elemento della lista e ne ritorna il
valore. Notate che ciò è diverso da
li[-1], che ritorna un valore ma non
cambia la lista ed è diverso anche da
li.remove(valore),
che cambia la lista ma non ritorna un valore.
|
Esempio 2.22. Operatori su liste
>>> li = ['a', 'b', 'mpilgrim']
>>> li = li + ['example', 'new']
>>> li
['a', 'b', 'mpilgrim', 'example', 'new']
>>> li += ['two']
>>> li
['a', 'b', 'mpilgrim', 'example', 'new', 'two']
>>> li = [1, 2] * 3
>>> li
[1, 2, 1, 2, 1, 2]
|
Le liste possono anche essere concatenate con l'operatore
+.
lista =
lista +
altralista
ha lo stesso risultato di
lista.extend(altralista),
ma l'operatore + ritorna una nuova lista
(concatenata) come valore, mentre extend modifica la lista
già esistente. Pertanto, extend è più veloce, in
modo particolare in riferimento a grandi liste.
|
|
Python supporta l'operatore +=.
li += ['two'] equivale a
li.extend(['two']). L'operatore
+= funziona con liste, stringhe ed interi
e può essere aggiunto alle classi create dal programmatore.
(Per le classi, vedi il capitolo 3.)
|
|
L'operatore * ripete gli elementi di una
lista.
li = [1, 2] * 3 è uguale a
li = [1, 2] + [1, 2] + [1, 2], che
concatena le tre liste in una sola.
|