Sei sulla pagina 1di 5

Programmare in Python - a.s. 2020-2021 Prof.

Mauro Gregori

Lezione su liste e stringhe


In Python qualunque oggetto in grado di essere trattato come una sequenza è definito un oggetto iterable
(in italiano “iterabile”). Sono oggetti iterabili:
• le liste;
• le stringhe (sequenze di caratteri non direttamente modificabili);
• l'oggetto restituito dalla funzione range();
• altri tipi di dati che vedremo in seguito (tuple,…).

La funzione list()
list() è un metodo (funzione) che si utilizza per creare le liste vuote o per creare liste con determinati
valori.
• Creare liste vuote:
>>> vuota = list()
>>> vuota
[]
Che è equivalente a eseguire:
>>> vuota2 = []
>>> vuota2
[]
• Creare nuove liste contenenti elementi.
Ad esempio possiamo creare una lista di numeri interi da 0 a n usando la funzione range(n+1):
>>> interi=list(range(5))
>>> interi
[0, 1, 2, 3, 4]
Oppure possiamo creare la lista dei caratteri costituenti una data stringa:
>>> caratteri=list("Mauro Gregori")
>>> caratteri
['M', 'a', 'u', 'r', 'o', ' ', 'G', 'r', 'e', 'g', 'o', 'r', 'i']

La funzione len()
len(x) calcola la lunghezza di x (dove x è una lista o una stringa), cioè il numero dei suoi elementi.

>>> nome = "pippo e pluto"


>>> len(nome)
13
>>> len(interi)
5
Possibile uso di len()

>>> for i in range(len(numeri)):


print(numeri[i], end = " ")
0 1 2 3 4

Equivalentemente possiamo ottenere lo stesso risultato in questo modo:


Programmare in Python - a.s. 2020-2021 Prof. Mauro Gregori

>>> for e in numeri:


print(e, end = " ")
0 1 2 3 4

Domanda: perché e quando sfruttare il primo modo, che utilizza l’indice per accedere agli elementi della
lista, invece del secondo modo, che lavora direttamente sugli elementi che compongono la lista?
Semplice! Quando dovremo operare sugli elementi della lista indipendentemente dalla loro posizione (leggi
indice) useremo il secondo modo, altrimenti il primo.
Vediamo qualche esempio:

>>> for i in range(len(numeri)):


print(numeri[i] ** i, end = ", ")
1, 1, 4, 27, 256,

>>> albero = "alberoDiNatale"


>>> for i in range(len(albero)):
print(albero[i] * (i+1))

a
ll
bbb
eeee
rrrrr
oooooo
DDDDDDD
iiiiiiii
NNNNNNNNN
aaaaaaaaaa
ttttttttttt
aaaaaaaaaaaa
lllllllllllll
eeeeeeeeeeeeee

Modificare una lista


Modifica di un elemento
Eseguito il seguente assegnamento

>>> nomi = ['Anna', 'Mauro', 'Lucio', 'Samuele', 'Pippo']

ipotizziamo di voler modificare 'Lucio'in 'Lucia'.


L’operazione è molto semplice e consiste nel considerare ogni elemento della lista (identificato dal suo
indice) come una variabile ed eseguire su di esso l’assegnamento del nuovo valore:

>>> nomi[2] = 'Lucia'

Ora la lista nomi conterrà

>>> nomi
['Anna', 'Mauro', 'Lucia', 'Samuele', 'Pippo']
Programmare in Python - a.s. 2020-2021 Prof. Mauro Gregori

Attenzione! Questa operazione non è consentita sulle stringhe (Ricordate?! Non sono direttamente
modificabili!). Infatti:

>>> p = "Pippo"
>>> p[1]
'i'
>>> p[1] = "a"
Traceback (most recent call last):
File "<pyshell#42>", line 1, in <module>
p[1] = "a"
TypeError: 'str' object does not support item assignment

Eliminazione di un elemento (N.B. solo sulle liste, non sulle stringhe!)


Per cancellare un elemento sono disponibili molti metodi, ma ora ne vedremo solo due:
• il primo utilizza il metodo remove() agisce tramite il valore dell’elemento da cancellare;
• il secondo utilizza l’istruzione del e agisce direttamente sull’elemento della lista tramite il suo
indice.
Vediamo il primo metodo:

>>> nomi.remove("Samuele")
>>> nomi
['Anna', 'Mauro', 'Lucia', 'Pippo']

Attenzione! Tentare di cancellare un elemento non presente nella lista causa un errore:

>>> nomi.remove("Carlo")
Traceback (most recent call last):
File "<pyshell#45>", line 1, in <module>
nomi.remove("Carlo")
ValueError: list.remove(x): x not in list

Poiché il programmatore al tempo della scrittura del programma non può prevedere quali valori saranno
presenti in lista al momento dell’esecuzione di una cancellazione, per evitare il precedente errore si dovrà
condizionare l’operazione di cancellazione al controllo dell’effettiva presenza del valore da eliminare,
tramite il costrutto di selezione if…else…:

>>> if "Maria" in nomi:


nomi.remove("Maria")
else: print("Dato inesistente")

Dato inesistente

Vediamo ora il secondo metodo:

>>> del nomi[1]


>>> nomi
['Anna', 'Lucia', 'Pippo']
Programmare in Python - a.s. 2020-2021 Prof. Mauro Gregori

Anche in questo caso il tentativo di eliminare un elemento utilizzando un indice inesistente causerà un
errore:

>>> del nomi[7]


Traceback (most recent call last):
File "<pyshell#53>", line 1, in <module>
del nomi[7]
IndexError: list assignment index out of range

Slicing (di liste e stringhe)


È possibile estrarre più elementi da una lista (o da una stringa) con la tecnica dello slicing
(dall’inglese to slice “affettare”) che utilizza due indici separati dal simbolo “:”, il primo indice
indicante il primo elemento della lista incluso nella “fetta”, il secondo indice il primo elemento
della lista escluso.

>>> nomi = ['Anna', 'Mauro', 'Lucio', 'Samuele', 'Pippo']


>>> nomi[1:4]
['Mauro', 'Lucio', 'Samuele']
>>> nomi[0:3]
['Anna', 'Mauro', 'Lucio']

Omettere il primo indice significa iniziare dal primo elemento della lista (equivale a utilizzare l’indice 0),
mentre omettere il secondo indice significa includere nello slicing tutti gli elementi fino all’ultimo.

>>> nomi[:3]
['Anna', 'Mauro', 'Lucio']
>>> nomi[1:]
['Mauro', 'Lucio', 'Samuele', 'Pippo']
>>> nomi[:]
['Anna', 'Mauro', 'Lucio', 'Samuele', 'Pippo']

Nell’ultimo esempio si dimostra che il non specificare sia l’indice d’inizio che quello di fine dello slicing
permette ti catturare tutti gli elementi della lista. A cosa può essere utile questa operazione? Serve a creare
una copia della lista d’origine:

>>> nomi2 = nomi[:] # assegnamento con lo slicing


>>> nomi2
['Anna', 'Mauro', 'Lucio', 'Samuele', 'Pippo']

Una domanda sorge spontanea: non sarebbe bastato il seguente assegnamento per ottenere identico
risultato?!

>>> nomi3 = nomi # assegnamento senza slicing


>>> nomi3
['Anna', 'Mauro', 'Lucio', 'Samuele', 'Pippo']

Apparentemente sì, ma in realtà i due assegnamenti producono un risultato completamente diverso.


Proviamo a eliminare l’elemento d’indice 2 dalla lista originaria nomi:
Programmare in Python - a.s. 2020-2021 Prof. Mauro Gregori

>>> del nomi[2]


>>> nomi
['Anna', 'Mauro', 'Samuele', 'Pippo']

Ora anche in nome3 (quella creata con l’assegnamento senza lo slicing) è scomparsa la stringa ‘Lucio’

>>> nomi3
['Anna', 'Mauro', 'Samuele', 'Pippo']

Questo dimostra che nomi e nomi3 in realtà sono identificatori diversi che “puntano” alla stessa lista
(studiando più in profondità Python scopriremmo che nomi e nomi3 rappresentato l’indirizzo in memoria
del primo elemento dell’unica lista).
Sorprendentemente invece scopriamo che in nomi2 la stringa ‘Lucio’ esiste ancora, il che significa che
l’assegnamento con lo slicing ha realmente creato una seconda copia della lista nomi con identificatore
nomi3.

>>> nomi2
['Anna', 'Mauro', 'Lucio', 'Samuele', 'Pippo']