In Python è possibile definire una lista, alla quale si potrà attribuire un nome, inserendo degli elementi tra parentesi quadre ("[..]"). Chi già lavora con altri linguaggi per la programmazione o lo sviluppo conoscerà sicuramente gli array, o "vettori", che sono delle variabili destinate a contenere ulteriori variabili; sintatticamente e concettuamente le liste possono ricordare gli array, ma il loro funzionamento presenta delle peculiarità che le rendono differenti.
Di base una lista può esistere ma essere vuota, cioè non presentare alcun elemento al suo interno:
# Esempio di lista vuota
nome_lista = []
Nel caso in cui una lista non sia vuota, sarà necessario separare gli elementi che la compongono tramite una virgola. E’ possibile quindi definire liste che contengano elementi associati ad un solo tipo di dato:
# Esempio di lista contenente unicamente valori numerici
nome_lista = [15, 25, 35, 45, 55]
# Esempio di lista contenente unicamente delle stringhe
nome_lista = ['Homer', 'Bart', 'Lisa']
Così come si potranno creare delle liste che presentino elementi di diversa natura:
# Esempio di lista contenente elementi di diverso tipo
# numeri e stringhe
nome_lista = [65, 'Homer', 7.3]
E’ infine consentita anche la creazione di liste annidate (nested list), cioè liste che hanno tra i propri elementi altre liste
# Esempio di lista annidata
nome_lista = ['Homer', 3.7, 10, [29, 39, 49]].
Generazione automatica delle liste di interi
range() è una funzione nativa di Python (o più propriamente un "immutable sequence type") concepita per generare automaticamente una lista sulla base di un intervallo di valori o di un valore numerico passato come argomento; essa si rivela particolarmente utile quando si devono definire liste formate da una grande quantità di elementi numerici. Nel caso di un parametro espresso sotto forma intervallo si avrà che un’istruzione come la seguente:
# Utilizzo di range() per generare
# una lista sulla base di un intervallo
>>> range(1,8)
porterà alla generazione di una lista composta da 7 elementi:
[1, 2, 3, 4, 5, 6, 7]
Tali elementi saranno il risultato della chiamata alla funzione range() che valuterà i due argomenti dell’intervallo restituendo una lista contenente tutti i valori interi a partire dal primo, incluso nella lista, fino ad arrivare al secondo, escluso invece dalla lista. I due argomenti dell’intervallo potranno essere seguiti da un terzo argomento denominato step; esso specifica l’intervallo tra valori successivi, motivo per il quale se, per esempio, si volesse ottenere una lista composta dai soli numeri dispari copresi tra "1" e "8" si potrebbe operare in questo modo:
# Utilizzo di range() per generare
# una lista sulla base di un intervallo
# con step pari a 2
>>> range(1,8,2)
# lista generata
# [1, 3, 5, 7]
Quando invece si passa alla funzione un intero come nell’esempio proposto di seguito:
# Utilizzo di range() per generare
# una lista sulla base di un intero
>>> range(8)
si avrà come risultato una lista popolata in questo modo:
[0, 1, 2, 3, 4, 5, 6, 7]
Gli elementi presenti saranno quindi 8, ponendo lo "0" come elemento e (non) valore iniziale.
Indicizzazione degli elementi di una lista
Di default e liste in Python prevedono che gli elementi interni vengano indicizzati numericamente; l’indicizzazione partirà da "0", per cui una lista composta da tre elementi avrà come indici "0", "1" e "2". Ne consegue che un elemento specifico di una lista potrà essere richiamato tramite il suo indice, come nell’esempio seguente:
# Accesso ad un elemento di una lista
# attraverso il suo indice
# definizione degli elementi in lista
>>> nome_lista = ['a','b','c','d','e']
# accesso all'elemento con indice "3"
>>> nome_lista[3]
L’elemento richiamato sarà in questo caso "d", cioè il quarto inserito in lista, questo perché "a" è associato all’indice "0", "b" a "1", "c" a "2" e di conseguenza "d" ha come indice "3".
L’accesso agli elementi in lista potrebbe avvenire anche tramite indicizzazione negativa, dove l’ultimo elemento avrà come indice "-1", il penultimo "-2" e così via. Una chiamata come la seguente avrà quindi il risultato di consentire l’accesso all’elemento "a".
# Accesso ad un elemento di una lista
# attraverso il indice negativo
# definizione degli elementi in lista
>>> nome_lista = ['a','b','c','d','e']
# accesso all'elemento con indice "-5"
>>> nome_lista[-5]
E’ inoltre possibile accedere agli elementi di una lista sulla base di un intervallo di valori; si faccia attenzione al fatto che i due componenti dell’intervallo corrisponderanno ai numeri indice, motivo per il quale un’espressione come questa:
# Accesso a più elementi di una lista
# attraverso un intervallo
# definizione degli elementi in lista
>>> nome_lista = ['a','b','c','d','e']
# accesso agli elementi con intervallo "0:2"
>>> nome_lista[0:2]
consentirà di accedere agli elementi "a", "b", cioè a quelli il cui indice va da "0" a "2" (escluso).
Il simbolo dei due punti (":"), utilizzato in precedenza per la definizione dell’intervallo, prende il nome di slicing operator. Esso potrà essere utilizzato anche per altri scopi, come per esempio definire l’indice dal quale partire per l’accesso ai dati:
# Accesso a più elementi di una lista
# a partire da un indice specifico
# definizione degli elementi in lista
>>> nome_lista = ['a','b','c','d','e']
# accesso al primo elemento in lista ('a') tramite indice negativo
# gli ultimi 4 elementi verranno esclusi
>>> nome_lista[:-4]
# accesso a partire dal terzo elemento fino all'ultimo
# 'c', 'd' ed 'e'
>>> nome_lista[2:]
# accesso a tutti gli elementi in lista
>>> nome_lista[:]
Come descritto nel prossimo capitolo, Python dispone di costrutti che consentono di effettuare operazioni più avanzate rispetto al semplice accesso ai valori, come per esempio quelli dedicati alla manipolazione delle liste.