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)