1
FONDAMENTI DI PROGRAMMAZIONE (L-Z)
PYTHON: LISTE 2
TIPI DI DATO COMPOSTI
▸ Numeri e stringhe consentono di memorizzare un singolo valore
▸ è vero che le stringhe sono sequenze di caratteri, ma “logicamente” sono un singolo valore (una
parola, una frase, etc.)
▸ Python offre tipi di dato composti che consentono la memorizzazione di collezioni di
valori, secondo diverse modalità (liste, insiemi, dizionari, …)
▸ Liste: sequenze ordinate di elementi, anche eterogenei, espandibili e contraibili a
piacere, ad accesso posizionale
PYTHON: LISTE 3
SINTASSI
▸ Le liste in Python si denotano racchiudendone gli elementi tra parentesi quadre, separati da
virgola
▸ e.g. l = [1, ‘two’, 3]
▸ La lista vuota si specifica con le sole parentesi quadre (l = [])
▸ È possibile accedere agli elementi di una lista conoscendone la posizione
▸ e.g. l = [1, ‘two’, 3], l[0] == 1
▸ È possibile espandere e contrarre la lista a piacere
▸ e.g. l = [1, ‘two’, 3], l.append(4.0) causa l[3] == 4.0, del l[1] causa l == [1, 3, 4.0]
PYTHON: LISTE 4
OPERAZIONI COMUNI
▸ È possibile conoscere la lunghezza di una lista usando la funzione len()
▸ e.g. l = [1, ‘two’, 3], len(l) == 3
▸ È possibile applicare ad una lista gli operatori + (concatenazione) e * (ripetizione)
▸ e.g. l = [1, ‘two’, 3], l + l = [1, 'two', 3, 1, 'two', 3]
▸ e.g. l = [1, ‘two’, 3], l * 3 = [1, 'two', 3, 1, 'two', 3, 1, 'two', 3]
▸ È anche possibile innestare liste
▸ e.g. l = [1, [‘two’], 3], l[1] == ['two']
PYTHON: LISTE 5
SLICING
▸ La notazione posizionale può essere usata per accedere a parti della lista
▸ e.g. l = [1, 2, 3, 4, 5], l[1:-1] == [2, 3, 4]
▸ notare l’utilizzo di numeri negativi come indici che partono dalla fine della lista!
▸ Questa operazione, denominata slicing, produce una copia della lista, indipendente
dall’originale
▸ e.g. l1 = [1, 2, 3, 4, 5], l2 = l1[1:-1], l1[1] = 0 allora l2[0] == 2
▸ L’assegnamento invece riferisce la stessa lista!
▸ e.g. l1 = [1, 2, 3, 4, 5], l2 = l1, l1[1] = 0 allora l2[0] == 0
PYTHON: STRINGHE 6
APPROFONDIMENTO SLICING
▸ Operazione valida per qualunque oggetto "iterabile"
▸ anche le stringhe dunque!
▸ Slicing con “passo”: aggiungendo un terzo argomento all’operatore di slicing si specifica il
“passo” con cui distanziare gli elementi (default = 1)
▸ E.g.: s = “abracadabra” allora s[::2] == “arcdba”
▸ Il passo può anche essere negativo, nel qual caso la stringa viene scorsa dal fondo
▸ E.g.: s = “abracadabra” allora s[::-2] == “abdcra”
PYTHON: LISTE 7
COPIA O RIFERIMENTO
▸ Le variabili associate a valori di tipo numerico, stringa, e booleano mantengono una
copia indipendente del valore
▸ Le variabili associate a qualunque altro “oggetto” (e.g. i tipi composti) mantengono
invece un riferimento allo stesso valore (o meglio, alla cella di memoria che lo contiene)
▸ E.g.: ▸ E.g.:
x=1 l1 = [1,2,3]
y=x l2 = l1
y == 1 l2 == [1,2,3]
y=2 l2[0] = ‘x’
x == 1 l1[0] == ‘x’
PYTHON: LISTE 8
OFF-TOPIC: PASSAGGIO DEI PARAMETRI NELLE FUNZIONI
▸ Il passaggio dei parametri durante l’invocazione di una funzione in Python avviene
sempre per copia del riferimento
▸ in caso di tipi semplici, non c’è alcun riferimento dunque si copia il valore
▸ in caso di tipi composti, può dunque succedere di avere due variabili che “puntano”
allo stesso valore
▸ Che situazioni indesiderate può generare il secondo caso?
PYTHON: LISTE 9
OFF-TOPIC: PASSAGGIO DEI PARAMETRI NELLE FUNZIONI
▸ E.g.: ▸ E.g.:
def selfAppend(l): def reset(l):
"Appends l to itself" “Resets l to the empty list"
l.append(l[:]) l = []
print(f'l: {l}') print(f'l: {l}')
l1 = [1,2,3] l1 = [1,2,3]
selfAppend(l1) reset(l1)
print(f'l1: {l1}') print(f'l1: {l1}')
PYTHON: LISTE 10
ITERAZIONE
▸ Elemento per elemento, utilizzando l’operatore in
▸ e.g. (modalità interattiva):
l = [1, 2, 3]
for e in l:
e
▸ Posizione per posizione, utilizzando in combinato con range() e len()
▸ e.g. (modalità interattiva):
l = [1, 2, 3]
for i in range(len(l)):
l[i]
PYTHON: LISTE 11
METODI
▸ I metodi di un “oggetto” (tipo di dato) Python sono funzioni messe a disposizione da ogni istanza
dell’oggetto, invocate per mezzo dell’operatore “.”
▸ append() per aggiungere un elemento in coda alla lista
▸ insert() per inserire un elemento in una posizione specifica (e.g. l=[1,2,3], l.insert(1, ‘one’) allora l == [1,
‘one’, 2, 3])
▸ remove() per rimuovere la prima occorrenza di uno specifico elemento dalla lista (e.g. l=[1,2,3,2],
l.remove(2) allora l == [1, 3, 2])
▸ pop() per prelevare l’elemento a una specifica posizione (e.g. l=[1,2,3], l.pop(2) allora l == [1, 2])
PYTHON: LISTE 12
METODI
▸ […continua]
▸ index() per trovare la prima posizione (da sinistra) a cui compare uno specifico elemento (e.g. l=[1,2,3,2],
i=l.index(2) allora i == 1)
▸ count() per contare le occorrenze di uno specifico elemento (e.g. l=[1,2,3,2], c=l.count(2) allora c == 2)
▸ sort() per ordinare (ascendente) gli elementi nella lista (e.g. l=[1,4,3,2], l.sort() allora l == [1,2,3,4])
▸ attenzione: supportato solo per valori omogenei!
▸ reverse() per ribaltare la lista (e.g. l=[1,2,3,4], l.reverse() allora l == [4,3,2,1])
PYTHON: LISTE 13
LIST COMPREHENSION
▸ Meccanismo del linguaggio Python che consente di creare liste in maniera concisa
▸ creandone gli elementi usando la combinazione for in range
▸ elaborando gli elementi di un’altra lista (o di un qualunque oggetto iterabile)
▸ filtrando gli elementi di un’altra lista (o di un qualunque oggetto iterabile)
▸ Struttura: [<espressione> for <elemento> in <iterabile> if <condizione>]
▸ E.g. (modalità interattiva):
[x**2 for x in range(10) if (x % 2) != 0]
>>> [1, 9, 25, 49, 81]
PYTHON: LISTE 14
NESTED LIST COMPREHENSION
▸ È possibile innestare più list comprehension
▸ E.g. (modalità interattiva):
matrix = [
[1, 2, 3],
[4, 5, 6]
]
[ [row[i] for row in matrix] for i in range(len(matrix[0])) ]
>>> [[1, 4], [2, 5], [3, 6]]
PYTHON: LISTE 15
RIMOZIONE DUPLICATI
▸ Rimuovere duplicati da una lista è un’operazione piuttosto comune
▸ Il metodo più semplice è trasformare la lista in un insieme (set), ovvero, una collezione
non ordinata (no accesso posizionale) di elementi, anche eterogenei, espandibili e
contraibili a piacere, che non ammette duplicati
▸ E.g.: l = [1, 2, 3, 2], s = set(l) allora s == {1, 2, 3}
▸ Il set vuoto si crea con la funzione set(): e.g. s = set()
▸ Notate le parentesi graffe anzichè quadre
PYTHON: LISTE 16
PARENTESI SUI SET
▸ Utile rimpiazzo per le liste in caso servano operatori insiemistici
▸ E.g.:
s1 = set(‘abracadabra’), s2 = set(‘alakazam’) allora s1 == {'a', 'c', 'b', 'd', ‘r’}, s2 == {'a', 'l', 'z', 'm', 'k'}
▸ unione (|): e.g. s1 | s2 == {'a', 'l', 'z', 'c', 'b', 'm', 'k', 'd', 'r'}
▸ intersezione (&): e.g. s1 & s2 == {‘a’}
▸ differenza (-): e.g. s1 - s2 == {'r', 'b', 'd', 'c'}
▸ differenza simmetrica (^): e.g. s1 ^ s2 == {'b', 'd', 'l', 'm', 'k', 'r', 'z', ‘c’}
▸ Supporto ad aggiunta (add()) e rimozione (remove()) elementi, set comprehension
PYTHON: LISTE 17
ERRORI
▸ A questo punto vi sarà capitato di fare errori
▸ di sintassi: lo script non parte
▸ eccezioni: l’interprete Python vi mostra un messaggio che inizia per “Traceback (most
recent call last): …”
▸ Le eccezioni sono errori di esecuzione che il programmatore può gestire
▸ il messaggio dice qual è l’errore e dov’è
PYTHON: LISTE 18
GESTIONE ERRORI
▸ Python offre il seguente costrutto per gestire eccezioni
try:
<codice pericoloso>
except <Errore>:
<gestione errore>
▸ E.g. (modalità script):
ok = False
while not ok:
try:
n = int(input('Inserisci numero intero: '))
ok = True
except ValueError:
print('Non si è inserito un numero intero’)