Laboratorio di Python (con Linux) - 6a lezione

Transcript

Laboratorio di Python (con Linux) - 6a lezione
Preliminari
Liste
Laboratorio di Python (con Linux)
6a lezione
Giulio Pellitta
Università di Bologna
11, 13 aprile 2012
Giulio Pellitta
Laboratorio di Python (con Linux)
Preliminari
Liste
Sommario
1
Preliminari
2
Liste
Giulio Pellitta
Laboratorio di Python (con Linux)
Preliminari
Liste
Riepilogo su Python
Ne abbiamo fatta di strada a partire dall’uso come calcolatrice. . .
interi, float, booleani
stringhe, liste, tuple
print/return, # (commento)
errore sintattico/semantico/runtime
variabili locali/globali, parametri (opzionali e non)
if/else/elif, break/continue
tipaggio dinamico, script/modalità interattiva, import
iterazione (determinata/indeterminata), ricorsione
Giulio Pellitta
Laboratorio di Python (con Linux)
Preliminari
Liste
Metodi
Un metodo è una specie di funzione che si chiama a partire da
una espressione di un certo tipo usando la notazione
espressione.metodo(argomento1,argomento2,. . . ).
Esempio: ’Cane’.upper() [= ’CANE’]
Sintassi tipica dell’ambito object-oriented programming (noi non
vogliamo fare OOP, quindi i metodi non li scriveremo ma ci
limiteremo ad usarli).
Tipi diversi hanno metodi diversi.
Giulio Pellitta
Laboratorio di Python (con Linux)
Preliminari
Liste
Manipolazione stringhe
Il tipo str ha dei metodi interessanti come split e
splitlines.
1
2
3
4
line=’Il mio cane si chiama Fido.’
line.split() [= [’Il’, ’mio’, ’cane’, ’si’,
’chiama’, ’Fido.’]]
text=’Mary had a little lamb,\nIts fleece was
white as snow;\nAnd everywhere that Mary
went,\nThe lamb was sure to go.’
text.splitlines() [=[’Mary had a little lamb,’,
’Its fleece was white as snow;’, ’And everywhere
that Mary went,’, ’The lamb was sure to go.’]]
Entrambi prendono argomenti opzionali. Ad esempio
text.splitlines() è equivalente a text.split(’\n’)
(dove \n indica il carattere di fine riga).
Vedi anche http://docs.python.org/library/
stdtypes.html#string-methods.
Giulio Pellitta
Laboratorio di Python (con Linux)
Preliminari
Liste
Leggere files
Python ha un tipo di dato File, completo di una serie di metodi.
1
f = open(’./esempio.py’,’r’)
# apre il file ’./esempio.py’ in lettura (r=read);
2
lines = f.readlines()
# contiene la lista di tutte le righe del file.
Per ora questo ci basta.
Non approfondiamo cosa succede se il file non esiste o simili.
Per i più curiosi, altre informazioni su http://docs.python.
org/library/stdtypes.html#file-objects.
Giulio Pellitta
Laboratorio di Python (con Linux)
Preliminari
Liste
Liste
Le liste sono sequenze mutabili di elementi.
Se ho una sequenza a cui aggiungere/togliere valori o da
modificare uso le liste.
1
2
3
#
#
4
#
#
L=[’a’,’b’,’c’]
T=(’a’,’b’,’c’)
L[0]=7
L diventa [7,’b’,’c’]
T[0]=7 causa errore di runtime. Cosa posso fare invece?
T=(7,)+T[1:]
Molto più inefficiente (le tuple sono ottimizzate per la lettura).
E comunque non è la stessa cosa (ho assegnato a T un nuovo
oggetto, non ne ho cambiato il valore).
Giulio Pellitta
Laboratorio di Python (con Linux)
Preliminari
Liste
Operazioni sulle liste
Metodi ed altro
L.append(x) è un metodo che appende un elemento x in
fondo alla lista L.
Per inserire un elemento x in una posizione qualsiasi della lista L
usiamo il metodo L.insert(k,x).
Per togliere l’elemento in posizione k di una lista si usa lo
statement del L[k].
help(list) nella shell di Python dà l’elenco dei metodi.
Possiamo avere funzioni equivalenti. Questa ad esempio cancella
l’elemento di posto k di una lista (come del).
def mydel(L,k):
L[:k+1]=L[:k]
Con le slice si può mutare una porzione di lista, come appena visto
(non possiamo soltanto modificare un elemento per volta).
Giulio Pellitta
Laboratorio di Python (con Linux)
Preliminari
Liste
Attenzione!
1
a=[1,2,3]
2
b=a
3
a[0]=-5
# Modifico l’oggetto puntato dalla variabile a
4
print b[0] [= -5]
# a e b puntano allo stesso oggetto, quindi ho modificato anche
l’oggetto puntato da b.
5
b=a[:]
# Così invece metto in b una copia dell’oggetto puntato da a (sono
distinti).
6
a[0]=7
# b[0] rimane -5.
Giulio Pellitta
Laboratorio di Python (con Linux)
Preliminari
Liste
Esercizi
1
Definire una funzione myappend(L,k) che accoda l’elemento k
alla lista L.
2
Si costruisca una funzione “flatten” che data una lista di liste di
interi a, restitutisca una nuova lista b, distinta da quella in input,
che contenga tutti e soli gli interi in a, nel loro ordine naturale.
Assieme alla lista b, flatten deve restituire il numero di interi
distinti in b.
3
Scrivere un programma che scelga a caso una stringa tra quelle
presenti in un file.
4
Crivello di Eratostene (calcolo numeri primi fino a n). Esercizio
per casa: scrivere la soluzione in un file chiamato
eratostene.cognome.nome.py e mandarlo via email a
[email protected] entro il prossimo laboratorio
(subject email: “eratostene”).
Giulio Pellitta
Laboratorio di Python (con Linux)
Preliminari
Liste
Suggerimenti
1
2
3
4
Usare le slice per mutare una porzione di lista opportuna.
Suddividere il programma in varie funzioni. Per cominciare
controllare che la lista sia ben fatta (cioè che sia effettivamente
una lista di liste di interi). Poi inserire i vari numeri con l’algoritmo
insertionsort, contando le varie occorrenze.
Usare i metodi del tipo str ed il modulo random.
Prendere l’algortimo in una forma elementare come la seguente.
1
2
3
4
Creare una lista di interi consecutivi da 2 a n.
Porre p = 2, il primo numero primo.
Segnare nella lista tutti i multipli di p maggiori di p stesso
(2p, 3p, 4p, . . . ). Notare che alcuni di essi potrebbero già essere
stati segnati.
Se nella lista rimangono numeri maggiori di p non segnati porre
uguale a p il minimo di questi e ripetere dal passo precedente.
Altrimenti stop.
Facoltativo: una volta finito inserire √
alcune migliorie, come ad
esempio ripetere il ciclo solo fino a n e partire da 2 e dalla lista
3, 5, . . . (fino ad n o n − 1, a seconda della parità di n).
Giulio Pellitta
Laboratorio di Python (con Linux)
Preliminari
Liste
Primo esercizio
Soluzioni
def myappend(L,x):
L[len(L):]=[x]
def myappend2(L,x):
L[:]=L+[x]
Compatto ed efficiente.
Semplice e compatto.
Una slice lunga 1 al
posto di una lunga 0.
Ridefinire l’intera lista
è inefficiente.
Giulio Pellitta
Laboratorio di Python (con Linux)
Preliminari
Liste
Secondo esercizio
def is_list_of_list_of_int(L):
if not(isinstance(L,list)): return False
for i in L:
if not(is_list_of_int(i)): return False
return True
def is_list_of_int(L):
if type(L)!=list: return False
for i in L:
if type(i)!=int: return False
return True
Per prima cosa controlliamo che l’input abbia la forma giusta.
Notare la struttura comune dei due for.
Giulio Pellitta
Laboratorio di Python (con Linux)
Preliminari
Liste
def insert(L,x): #nessuna ambiguita' con il metodo
for i in range(len(L)): #parti dall'inizio di L
if x<=L[i]: #se trovi un elemento maggiore
L.insert(i,x)
return #inserisci li' x e stop
L.append(x)
def flatten(L):
if not(is_list_of_list_of_int(L)): return
(outL,nint)=([],0) #inizializzazione
for intList in L:
for i in intList:
nint+=i not in outL #booleani come int
insert(outL,i)
return (outL, nint)
Dividendo il programma in tante parti, non è difficile da fare.
Usare nomi di variabili significativi è cosa buona e giusta.
Giulio Pellitta
Laboratorio di Python (con Linux)
Preliminari
Liste
Terzo esercizio
def parole_da_file(filename):
import string
(text, W) = (open(filename,"r").readlines(), [])
for line in text:
for s in line.split():
s=togli_punteggiatura(s)
discard=s==''
for i in range(len(s)):
if not(s[i] in string.letters):
discard=True; break
if discard: continue
s=s.upper()
if s not in W: W.append(s)
return W
def togli_punteggiatura(s):
s=s.lstrip("`'"+'"').rstrip("`'.,;:!?"+'"')
return s
Giulio Pellitta
Laboratorio di Python (con Linux)
Preliminari
Liste
La funzione togli_punteggiatura tiene conto di casi come
punto., virgola,, “virgolette”, puntini... e simili, ma
non riconosce ogni possibile situazione.
Usa due metodi del tipo str per togliere prefissi e suffissi
composti di determinati caratteri.
parole_da_file prende (senza duplicati) la stringhe che
ripulite dalla punteggiatura risultano non vuote.
def random_word_from_file
(filename="/usr/share/doc/idle-python2.6/README.txt"):
import random
return ramdom.choice(parole_da_file(filename))
Giulio Pellitta
Laboratorio di Python (con Linux)