Oggetti e Metodi
In Python ogni valore, di qualsiasi tipo int
, float
, str
, list
, ecc., è un oggetto (object). Un oggetto oltre ad avere un valore ha anche delle funzioni speciali che sono strettamente legate agli oggetti di quel tipo e sono chiamate metodi. Un metodo è simile a una funzione ma si differenzia sopratutto nella sintassi con cui viene chiamato. Il metodo method
, su un certo oggetto obj
, è chiamato così obj.method(parametri)
. Se fosse stato una funzione la chiamata sarebbe stata method(obj, parametri)
. Vedremo più in là come si definiscono nuovi tipi e i relativi metodi. Per adesso ci limiteremo a considerare i metodi più utili dei tipi stringa (str
) e lista (list
).
Metodi delle Stringhe
Se si chiama la funzione help()
fornendogli in input il nome di un tipo si ottiene l'elenco documentato di tutti i metodi definiti per quel tipo. Se lo si fa per il tipo str
si ottiene una lista piuttosto lunga che qui sotto è riportata fortemente abbreviata:
>>> help(str)
Help on class str in module __builtin__:
class str(basestring)
| str(object) -> string
|
| Return a nice string representation of the object.
| If the argument is a string, the return value is the same object.
|
| Method resolution order:
| str
| basestring
| object
|
| Methods defined here:
|
| __add__(...)
| x.__add__(y) <==> x+y
|
| __contains__(...)
| x.__contains__(y) <==> y in x
.
.
.
| split(...)
| S.split([sep [,maxsplit]]) -> list of strings
|
| Return a list of the words in the string S, using sep as the
| delimiter string. If maxsplit is given, at most maxsplit
| splits are done. If sep is not specified or is None, any
| whitespace string is a separator and empty strings are removed
| from the result.
|
| splitlines(...)
| S.splitlines([keepends]) -> list of strings
|
| Return a list of the lines in S, breaking at line boundaries.
| Line breaks are not included in the resulting list unless keepends
| is given and true.
.
.
.
I metodi il cui nome inizia e finisce con due underscore __
hanno un significato speciale e saranno spiegati più avanti quando tratteremo le classi. Adesso ci interessano gli altri metodi.
Iniziamo con alcuni dei metodi più semplici ma comunque utili. I metodi lower()
e upper()
ritornano una copia della stringa in cui tutti i caratteri sono stati trasformati, rispettivamente, in minuscolo e in maiuscolo (ovviamente solo i caratteri alfabetici).
>>> 'Il Numero 1000'.lower()
'il numero 1000'
>>> 'il numero 1000'.upper()
'IL NUMERO 1000'
Il metodo count()
permette di contare il numero di occorrenze di una stringa nella stringa:
>>> a = "Tre Tigri Contro Tre Tigri"
>>> a.count('i')
4
>>> a.count('c')
0
>>> a.count('Tigri')
2
count()
può prendere anche fino a due parametri opzionali che restringono la ricerca delle occorrenze a una porzione della stringa:
>>> a.count('i', 9) # Conta nella stringa dall'indice 9 in poi
2
>>> a.count('i', 6, 9) # Dall'indice 6 all'indice 9 escluso
1
Come esempio d'uso di questi metodi vogliamo scrivere una funzione conta_vocali()
che conta il numero di vocali, minuscole e maiuscole, presenti nella stringa di input.
def conta_vocali(s):
s = s.lower() # Per contare anche le vocali maiuscole
count = 0
for v in 'aeiou':
count += s.count(v)
return count
def test(s):
print s, " Numero vocali:", conta_vocali(s)
test("Apelle Figlio di Apollo...")
test("Nn c sn vcl")
Il metodo find()
ritorna l'indice in cui inizia la prima occorrenza di una stringa se non ci sono occorrenze ritorna -1
.
>>> s = 'Apelle figlio di Apollo...'
>>> s.find('pollo')
18
>>> s.find('A', 1) # Cerca a partire dall'indice 1
17
>>> s.find('pelle', 2, 9) # Cerca tra l'indice 2 e il 9 escluso
-1
Il metodo splitlines()
ritorna la lista delle linee della stringa:
>>> testo = '''Prima linea,
seconda linea
e terza linea.'''
>>> testo.splitlines()
['Prima linea,', 'seconda linea', 'e terza linea.']
Se gli diamo il parametro opzionale True
anche i caratteri di fine linea sono ritornati.
Vediamo un esempio. Siamo interessati a scrivere una funzione rubrica
che prende in input due stringhe la prima contiene in ogni linea un nome, il carattere :
e poi un numero di telefono, la seconda stringa contiene un nome, e la funzione deve ritornare il numero di telefono relativo a quel nome. Se la prima stringa di input è
'''Marco Bianchi : 06 95666767
Giorgia Verdi : 347 899897898
Luisa Della Valle : 343 989820202'''
e la seconda stringa di input è 'della valle'
, la funzione ritorna '343 989820202'
. Per scrivere questa funzione è utile avere uno strumento per ottenere una sottostringa di una stringa (nel nostro caso la sottostringa del numero telefonico).
Fette di Sequenze (Slices)
In Python la sintassi delle parentesi quadre per accedere ad un valore di una sequenza in una certa posizione è molto più versatile di quanto abbiamo visto finora. Infatti, permette di ottenere una qualsiasi sottosequenza di velori consecutivi specificando l'indice d'inizio e quello di fine (escluso):
>>> s = 'Apelle figlio di Apollo.'
>>> s[1:6] # La sottostringa che inizia in 1 e termina in 5
'pelle'
>>> s[7:13] # La sottostringa che inizia in 7 e termina in 12
'figlio'
>>> s[7:] # La sottostringa che inizia in 7 e va fino alla fine della stringa
'figlio di Apollo.'
>>> s[:13] # La sottostringa che inizia all'inizio e termina in 12
'Apelle figlio'
Queste sottosequenze [a:b]
, nel gergo di Python, si chiamano slices.
Le parentesi quadre accettano anche inidici negativi, in questo caso sono contati dalla fine verso l'inizio della sequenza, con -1
che rappresenta l'ultima posizione:
>>> s[-1]
'.'
>>> s[-2]
'o'
>>> s[-3]
'l'
>>> s[-4]
'l'
>>> s[-0]
'A'
>>> s[-1:0]
''
>>> s[-4:-1]
'llo'
>>> s[-4:]
'llo.'
>>> s[:-4]
'Apelle figlio di Apo'
Siccome questa sintassi è comune a tutti i tipi sequenza può essere usata anche con le liste.
Ritorniamo ora al nostro problema di scrivere la funzione rubrica
:
def rubrica(elenco, nome):
elenco = elenco.lower().splitlines()
for e in elenco:
if e.find(nome) != -1:
pos = e.find(':')
return e[pos + 1:] # Numero di telefono
return ''
def test(elenco, nome):
print 'Ricerca il nome', '"'+nome+'" nell\'elenco:'
print elenco
print 'Numero telefono:', rubrica(elenco, nome)
print
elenco = '''Marco Bianchi : 06 95666767
Giorgia Verdi : 347 899897898
Luisa Della Valle : 343 989820202'''
test(elenco, 'della valle')
test(elenco, 'rossi')
test(elenco, 'giorgia')
Un'altro metodo utile delle stringhe è split()
che ritorna la lista delle sottostringhe della stringa che sono separate da o caratteri spazio o da una stringa passata come parametro:
>>> s = "Una frase d'esempio, non troppo lunga"
>>> s.split() # Il separatore di default è lo spazio
['Una', 'frase', "d'esempio,", 'non', 'troppo', 'lunga']
>>> s.split(',')
["Una frase d'esempio", ' non troppo lunga']
>>> s.split('p')
["Una frase d'esem", 'io, non tro', '', 'o lunga']
>>> s.split('pp')
["Una frase d'esempio, non tro", 'o lunga']
>>> s.split('p', 2) # Fa al massimo 2 separazioni
["Una frase d'esem", 'io, non tro', 'po lunga']
Un metodo che spesso risulta molto utile se usato in congiunzione con split
è replace
che sostituisce tutte le occorrenze di una data sottostringa con un'altra sottostringa:
>>> s = "mille non piu' mille"
>>> s.replace('mille', 'cento')
"cento non piu' cento"
>>> s.replace('Mille', 'cento')
"mille non piu' mille"
>>> s.replace('ll', 'st')
"miste non piu' miste"
Per illustarre l'uso di quet'ultimi due metodi, vogliamo scrivere una funzione camel
che prende in input una stringa "cammellata", ad es. questaFraseSenzaSpazi
, e ritorna la lista delle parole, che per l'esempio è ['questa', 'frase', 'senza', 'spazi']
.
def camel(s):
for c in 'ABCDEFGHILMNOPQRSTUVWXYZ':
s = s.replace(c, " "+c.lower())
return s.split()
def test(s):
print s
print camel(s)
print
test('questaFraseSenzaSpazi')
test('thisSentenceWithoutSpaces')
Ci sono molti altri metodi delle stringhe che non abbiamo qui trattato ma che sono ugualmente utili.
Metodi delle liste
Il metodo count
delle liste è simile all'omonimo metodo delle stringhe ma non permette di delimitare il conteggio delle occorrenze a una sottolista:
>>> lst = ['uno', 1, 'uno', 'due', 2, 1]
>>> lst.count(1)
2
>>> lst.count('uno')
2
L'analogo di find
per le liste è il metodo index
, ma quando il valore non è presente lancia un'eccezione:
>>> lst.index('due')
3
>>> lst.index(3)
Traceback (most recent call last):
File "<pyshell#61>", line 1, in <module>
lst.index(3)
ValueError: 3 is not in list
È anche posibile limitare opzionalmente la ricerca a una sottolista da un indice iniziale a uno finale.
Altri metodi molto importanti sono quelli che permettono di modificare una lista aggiungendo, inserendo o rimuovendo valori nella lista stessa, senza cioè creare una nuova altra. Il metodo append
aggiunge un valore in coda alla lista stessa:
>>> lst.append('tre')
>>> lst
['uno', 1, 'uno', 'due', 2, 1, 'tre']
>>> lst + ['quattro']
['uno', 1, 'uno', 'due', 2, 1, 'tre', 'quattro']
>>> lst
['uno', 1, 'uno', 'due', 2, 1, 'tre']
Il metodo insert
inserisce un valore in una certa posizione all'interno della lista:
>>> lst.insert(2, 'sei')
>>> lst
['uno', 1, 'sei', 'uno', 'due', 2, 1, 'tre']
>>> lst.insert(0, 'primo')
>>> lst
['primo', 'uno', 1, 'sei', 'uno', 'due', 2, 1, 'tre']
Mentre il metodo remove
rimuove la prima occorrenza di un valore dato e se non c'è lancia un'eccezione:
>>> lst.remove('uno')
>>> lst
['primo', 1, 'sei', 'uno', 'due', 2, 1, 'tre']
Il metodo pop
rimuove il valore in una posizione data e lo ritorna, di default la posizione è l'ultima:
>>> lst.pop()
'tre'
>>> lst
['primo', 1, 'sei', 'uno', 'due', 2, 1]
>>> lst.pop(2)
'sei'
>>> lst
['primo', 1, 'uno', 'due', 2, 1]
Come esempio d'uso vogliamo scrivere una funzione rot
che ruota verso destra una lista di una posizione, ad esempio se la lista di input è [1,2,3,4,5]
la funzione la modifica così [5,1,2,3,4]
. E poi possiamo anche scrivere una funzione rotate
che prende in input anche un intero k
e ruota la lista di k
posizioni.
def rot(lst):
last = lst.pop()
lst.insert(0, last)
def test(lst):
print lst
rot(lst)
print lst
print
test([1,2,3,4,5])
def rotate(lst, k):
for _ in range(k):
rot(lst)
def test2(lst, k):
print lst, " k =", k
rotate(lst, k)
print lst
print
test2([1,2,3,4,5], 2)
test2([1,2,3,4,5], 6)
Le liste non hanno tanti metodi come le stringhe, oltre a quelli visti ce ne solamente pochi altri.