P.25 Stringhe

Fino ad ora abbiamo utilizzato le stringhe in modo abbastanza semplice e istintivo ma questo tipo di “oggetti” in Python offrono varie possibilità di elaborazione. Una stringa è un messaggio, un testo o semplicemente una sequenza di caratteri delimitati da una coppia di virgolette.

Possiamo utilizzare, indifferentemente, le virgolette singole o doppie. Ecco due variabili che contengono delle stringhe definite nei due modi possibili:

a = “hello”
b = ‘world’

Possiamo combinare (o concatenare) due stringhe sommandole con il segno “+”:

a = "hello"
b = "world"
c = a + " " + b
print(c)

Eseguendo questo codice otterremo:

hello world

Le stringhe sono delimitate dal carattere virgoletta o virgoletta doppia che quindi assumono un ruolo speciale. Come dovremo fare se volessimo includere in una stringa delle virgolette? La stringa:

str = ‘l’albero di mele’ 

purtroppo genererà un errore! Python infatti si confonderebbe non capendo dove termina. Per poterla usare dobbiamo combinare i due tipi di virgolette:

str = “l’albero di mele” 

E analogamente, nel caso volessimo usare nel testo le virgolette doppie:

str = ‘John è un tipo “strano” ma sincero’

Abbiamo però anche la possibilità di dire a Python di ignorare la virgoletta in sé e trattarla come se fosse un semplice segno grafico facendola precedere dal simbolo di escape (\). Possiamo dunque definire una stringa:

str = “John è un tipo \“strano\” ma sincero”

oppure:

str = ‘l\’albero di mele’

Saluti personalizzati

Scriviamo un semplice programma che genera a caso un orario e quindi stampa un saluto personalizzato concatenando alcune stringhe. Se l’ora estratta e salvata nella variabile h è minore di 12, riceveremo un “buongiorno”, altrimenti visualizzeremo un “salve”:

import random
h = random.randint(0, 24)
print(h)
nome = "Paolo"
saluto = ""
if h < 12:
    saluto = "buongiorno"
else:
    saluto = "salve"
msg = saluto + " " + nome + " ore:" + str(h)
print(msg)

Qualche spunto:

  • modificate il programma inserendo più fasce orarie con saluti differenti: “buonanotte”, “buonasera” e così via.
  • Utilizzate l’ora reale importando il modulo datetime e poi estraendo l’ora di sistema con datetime.datetime.now().hour

Template

Abbiamo imparato a formattare le stringhe combinando delle parti “fisse” con valori presi dalle variabili. Negli esempi incontrati nella pagine precedenti abbiamo sempre utilizzato le stringhe formattate:

eta = 25
print(f“John ha {eta} anni”)

Quando Python incontra una stringa preceduta dal carattere f, tratta il suo contenuto come un “template”. All’interno del template ci saranno dei segnaposto delimitati da una coppia di parentesi graffe ({}). All’interno dei segnaposto possiamo inserire delle variabili e Python provvederà, prima di stampare la stringa, a sostituire il valore delle variabili ai relativi segnaposto.

All’interno dei segnaposto possiamo inserire anche delle semplici operazioni matematiche o combinazioni di variabili:

h = 10
l = 5
print(f“Area del triangolo= {(h*l)/2}”)

È possibile indicare un template utilizzando una tecnica differente. Creiamo una stringa e inseriamo un segnaposto vuoto:

txt = "Il tempo di volo è di {} ore"

Per associare una variabile al template scriveremo:

t = 4
print(txt.format(t))

Nel caso ci fossero più segnaposto, le variabili saranno sostituite nell’ordine in cui sono indicate con format(). Il metodo format() può quindi accogliere anche delle liste di parametri.

t = 8
h = 7000
txt = "Il tempo di volo è di {} ore e la quota di {} m"
print(txt.format(t, h))

Stringhe come liste

Una stringa è una lista di caratteri! Possiamo accedere ai singoli caratteri indicando il loro indice:

a = "Oggi piove"
print(a[1])

otterremo:

g

Ecco un programma che stampa ad una a una le lettere di una stringa:

for x in "banana":
  print(x)

Possiamo ricavare la lunghezza di una stringa passandola alla funzione len() (già utilizzata anche per le liste):

a = "Sole al nord"
print(len(a))

leggeremo nella shell:

12

Così come per le liste, per prendere una parte di una stringa utilizziamo le tecniche di slicing, indicando una coppia di indici:

txt = "nel mezzo del cammin"
print(txt[4:9])

Nella console vedremo apparire solo la parola:

mezzo

Specificando un solo indice prenderemo tutto il testo a partire dall’inizio:

print(txt[:9])

o dalla posizione indicata fino alla fine della stringa:

print(txt[10:])

Gli indici possono anche essere negativi e in questo caso partono dal fondo della stringa:

print(txt[2:-2])

Operazioni sulle stringhe

Se vogliamo verificare che un certo testo o una lettera sia presente in una stringa utilizzeremo in:

txt = "Nel mezzo del cammin di nostra vita"
if “del” in txt:
  print("ok")

L’operatore in non ci fornisce la posizione del termine cercato, ma indica solamente se è presente oppure no.

Se siamo interessati alla posizione di un elemento in una stringa useremo index():

txt = "nel mezzo del cammin"
n = txt.index("del")

Ricevendo dei testi da trasmissioni, inseriti dagli utilizzatori di un programma o estraendoli da file potrebbe capitare che questi abbiamo degli spazi di troppo alle loro estremità. Il metodo strip() rimuove gli spazi in eccesso posti all’inizio e alla fine della stringa:

txt = "  nel mezzo del cammin di nostra vita  "
print(f”#{txt}#”)
txt = txt.strip()
print(f”#{txt}#”)

In questo esempio stampiamo la stringa con un template che la circonda con dei simboli #, così che sia più facile osservare l’effetto di strip().

I metodi upper() e lower() trasformano tutti i caratteri in maiuscolo o in minuscolo:

txt = "Nel Mezzo Del Cammin Di Nostra Vita…"
print("maiuscolo:", txt.upper())
print("minuscolo:", txt.lower())

Ecco un esempio interattivo che chiede all’utilizzatore che testo cercare all’interno di una stringa. Il testo contenuto in txt presenta delle parole con lettere maiuscole e minuscole. Se noi volessimo verificare la presenza di “cammin”, purtroppo otterremmo una risposta negativa perché nella stringa txt la parola è riportata con l’iniziale maiuscola. Per Python “cammin” è diverso da “Cammin”! Utilizzando gli operatori upper() e lower() possiamo uniformare la stringa e il termine da cercare, ottenendo una ricerca “case insensitive”.

txt = "Nel Mezzo Del Cammin Di Nostra Vita…"
key = input("Che termine verifico? ")
if key.upper() in txt.upper():
  print("ok")
else:
  print("non trovato")

Per sostituire caratteri o parti della stringa utilizziamo replace():

txt = "  nel mezzo del cammin di nostra vita  "
print(txt.replace("e","*"))
print(txt.replace("vita","gita"))

A volte capita di ricevere degli elenchi di informazioni in modo testuale, separate da degli spazi o da un carattere speciale (virgole o punti e virgola).

a = "12,23,435,56,67,34,45"
b = "mele pere fragole kiwi"

È scomodo operare su questi dati trattandoli come stringhe, mentre sarebbe più logico trasformarli in liste di elementi. L’operazione è immediata con split(). Nell’esempio seguente suddividiamo la stringa b, ricavando una lista di nomi:

b = "mele pere fragole kiwi"
lista = b.split(" ")
for token in lista:
  print(token)

Un caso tipico è quello dei file CSV (Comma Separated Values, Valori separati da virgola), al cui interno troviamo tante righe di valori separati da virgole. Questi file si possono aprire con un foglio dati (es. Excel), oppure elaborare direttamente in Python.

Una tipica riga estratta da un CSV ha questo aspetto:

txt = "12,23,435,56,,67,34.4,45"

Per elaborarla faremo:

lista = txt.split(",")
for token in lista:
  print(token)

Abbiamo analizzato solo i metodi principaIi per lavorare con le stringhe. Le possibilità sono numerose e potete avere una panoramica più completa consultando delle risorse online:

https://www.w3schools.com/python/python_strings_methods.asp