Stringhe 1 - introduzione

Scarica zip esercizi

Naviga file online

Le stringhe sono sequenze immutabili di caratteri, e costituiscono uno dei tipi di base di Python. In questo foglio vedremo come manipolarle.

Riferimenti:

Che fare

  • scompatta lo zip in una cartella, dovresti ottenere qualcosa del genere:

strings
    strings1.ipynb
    strings1-sol.ipynb
    strings2.ipynb
    strings2-sol.ipynb
    strings3.ipynb
    strings3-sol.ipynb
    strings4.ipynb
    strings4-sol.ipynb
    jupman.py

ATTENZIONE: Per essere visualizzato correttamente, il file del notebook DEVE essere nella cartella szippata.

  • apri il Jupyter Notebook da quella cartella. Due cose dovrebbero aprirsi, prima una console e poi un browser. Il browser dovrebbe mostrare una lista di file: naviga la lista e apri il notebook strings1.ipynb

  • Prosegui leggendo il file degli esercizi, ogni tanto al suo interno troverai delle scritte ESERCIZIO, che ti chiederanno di scrivere dei comandi Python nelle celle successive. Gli esercizi sono graduati per difficoltà, da una stellina ✪ a quattro ✪✪✪✪

Scorciatoie da tastiera:

  • Per eseguire il codice Python dentro una cella di Jupyter, premi Control+Invio

  • Per eseguire il codice Python dentro una cella di Jupyter E selezionare la cella seguente, premi Shift+Invio

  • Per eseguire il codice Python dentro una cella di Jupyter E creare una nuova cella subito dopo, premi Alt+Invio

  • Se per caso il Notebook sembra inchiodato, prova a selezionare Kernel -> Restart

Creare stringhe

Ci sono diversi modi di definire una stringa.

Doppie virgolette, su una linea

[2]:
a = "la mia prima stringa, in doppie virgolette"
[3]:
print(a)
la mia prima stringa, in doppie virgolette

Virgolette singole, su una linea

Questo modo è equivalente al precedente.

[4]:
b = 'la mia seconda stringa, in virgolette singole'
[5]:
print(b)
la mia seconda stringa, in virgolette singole

Tre doppie virgolette, su più linee

[6]:
c = """la mia terza stringa
in triple doppie virgolette
quindi la posso mettere

su più righe"""
[7]:
print(c)
la mia terza stringa
in triple doppie virgolette
quindi la posso mettere

su più righe

Tre apici, su più linee

[1]:
d = '''la mia quarta stringa,
in tripli apici
può pure essere messa

su più linee
'''
[9]:
print(d)
la mia quarta stringa,
in triple doppie-virgolette
può pure essere messa

su più linee

Stampare - le celle

Per stampare una stringa possiamo usare la funzione print:

[10]:
print('ciao')
ciao

Notare che nella stampa non sono riportati gli apici.

Se invece scriviamo direttamente la stringa senza la print, vedremo gli apici:

[11]:
'ciao'
[11]:
'ciao'

Cosa succede se scriviamo la stringa coi doppi apici?

[12]:
"ciao"
[12]:
'ciao'

Vediamo che di default Jupyter la mostra con gli apici singoli

Lo stesso discorso si applica se assegnamo una stringa a una variabile:

[13]:
x = 'ciao'
[14]:
print(x)
ciao
[15]:
x
[15]:
'ciao'
[16]:
y = "ciao"
[17]:
print(y)
ciao
[18]:
y
[18]:
'ciao'

La stringa vuota

La stringa di lunghezza zero si rappresenta con due doppie virgolette "" o due apici singoli.

Nota che se anche scriviamo due doppie virgolette, Jupyter la mostra che inizia e finisce con un apice solo:

[19]:
""
[19]:
''

Lo stesso vale se associamo una stringa vuota ad una variabile:

[20]:
x = ""
[21]:
x
[21]:
''

Nota anche che se chiediamo a Jupyter di stampare con la print, non vedremo nulla:

[22]:
print("")

[23]:
print('')

Stampare più stringhe

Per stampare più stringhe su una linea ci sono diversi modi, cominciamo dal più semplice con la print

[24]:
x = "ciao"
y = "Python"

print(x,y)   # nota che nella stampa Python ha inserito uno spazio
ciao Python

Alla print possiamo aggiungere quanti parametri vogliamo, e possono anche essere mischiati con altri tipi come i numeri:

[25]:
x = "ciao"
y = "Python"
z = 3

print(x,y,z)
ciao Python 3

Lunghezza di una stringa

Per ottenere la lunghezza di una stringa (o in genere di qualunque sequenza), possiamo usare la funzione len:

[26]:
len("ciao")
[26]:
4
[27]:
len("")   # stringa vuota
[27]:
0
[28]:
len('')   # stringa vuota
[28]:
0

DOMANDA: Possiamo scrivere una cosa del genere?

"len"("ciao")
Mostra rispostaMostra soluzione
[29]:
# scrivi qui


DOMANDA: possiamo scrivere una cosa del genere? Cosa produce? un errore? un numero ? Quale?

len("len('ciao')")
Mostra risposta

DOMANDA: Cosa otteniamo se scriviamo così:

len(((((("ciao"))))))
  1. un errore

  2. la lunghezza della stringa

  3. qualcos’altro

Mostra risposta

Contare sequenze di escape: Nota che alcune sequenze particolari dette di escape come per esempio \t occupano meno spazi di quello che sembra (con len contano come 1), ma stampate ne occupano addirittura di più di 2 !!

Vediamo un esempio, nel prossimo paragrafo scenderemo nei dettagli:

[30]:
len('a\tb')
[30]:
3
[31]:
print('a\tb')
a       b

Stampare - sequenze di escape

Alcune sequenze di caratteri dette sequenze di escape sono speciali perchè invece di mostrare caratteri, forzano la stampa a fare cose particolari come andare a capo o inserire spazi extra. Queste sequenze sono sempre precedute da il carattere di backslash \:

Descrizione

Sequenza di escape

Ritorno a capo (linefeed)

\n

Tabulazione (ASCII tab)

\t

Esempio - ritorno a capo

[32]:
print("ciao\nmondo")
ciao
mondo

Notare che il ritorno a capo si verifica SOLO quando stampiamo con print, se invece immettiamo direttamente la stringa nella cella la vediamo tale e quale:

[33]:
"ciao\nmondo"
[33]:
'ciao\nmondo'

In una stringa si possono mettere quante sequenze si vuole:

[34]:
print("La nebbia a gl'irti colli\npiovigginando sale,\ne sotto il maestrale\nurla e biancheggia il mar;")
La nebbia a gl'irti colli
piovigginando sale,
e sotto il maestrale
urla e biancheggia il mar;

Esempio - tabulazione

[35]:
print("ciao\tmondo")
ciao    mondo
[36]:
print("ciao\tmondo\tcon\ttante\ttab")
ciao    mondo   con     tante   tab

ESERCIZIO: Visto che le sequenze di escape sono speciali, ci si può chiedere quanto siano lunghe. Usa la funzione len per stampare la lunghezza delle stringhe. Noti qualcosa di strano?

  • 'ab\ncd'

  • 'ab\tcd'

[37]:
# scrivi qui


ESERCIZIO: Prova a selezionare la sequenza di caratteri stampata nella precedente cella. Cosa ottieni ? Una sequenza di spazi, oppure un carattere singolo di tabulazione? Nota che questo può variare a seconda del programma che ha effettivamente stampato la stringa.

ESERCIZIO: trova UNA SOLA stringa che stampata con print venga mostrata come la seguente.

  • USA SOLO combinazioni di \t e \n

  • NON usare spazi

  • inizia e concludi la stringa con apice singolo

Questa  è
una

sfida   apparentemente      semplice
Mostra soluzione
[38]:
# scrivi qui


Questa  è
una

sfida   apparentemente          semplice

ESERCIZIO: Prova a trovare una stringa che stampata con print venga mostrata così, SENZA usare nessuno spazio, SENZA triple apici e usando SOLO combinazioni di \t e \n !!

At  te
n   tis
simame

n
te
Mostra soluzione
[39]:
# scrivi qui


At      te
n       tis
simame

n
te

Caratteri speciali: Per mettere caratteri speciali come il singolo apice ' o le doppie virgolette " , dobbiamo creare una cosiddetta sequenza di escape, cioè prima scriviamo il carattere backslash \ e poi lo facciamo seguire dal carattere speciale che ci interessa:

Descrizione

Sequenza di escape

Risultato a stampa

Apice singolo

\'

'

Doppio apice

\"

"

Backslash

\\

\

Esempio:

Stampiamo una stringa contenente un apice singolo ' e una doppia virgoletta "

[40]:
stringa = "Così metto \'apici\' e \"doppie virgolette\" nelle stringhe"
[41]:
print(stringa)
Così metto 'apici' e "doppie virgolette" nelle stringhe

Se una stringa inizia con doppi apici, all’interno possiamo usare liberamente singoli apici, anche senza backslash \:

[42]:
print("Non c'è problema")
Non c'è problema

Se inizia con singoli apici, possiamo liberamente usare doppie virgolette anche senza backslash \:

[43]:
print('Così è "se vi pare"')
Così è "se vi pare"

ESERCIZIO: Trova una stringa da stampare con la print che stampata mostri la sequenza seguente

  • la stringa DEVE iniziare e finire con singoli apici '

Questo "genio" delle stringhe vuole  /\\/ fregarmi \//\ con esercizi atroci O_o'
Mostra soluzione
[44]:
# scrivi qui


Questo "genio" delle stringhe vuole  /\\/ fregarmi \//\ con esercizi atroci O_o'

Caratteri Unicode: Quando abbiamo bisogno di caratteri particolari come ✪ che non sono disponibili sulla tastiera, possiamo rivolgerci ai caratteri Unicode. Ce ne sono tantissimi, e spesso per metterli in Python 3 è sufficiente un copia e incolla. Per esempio, andando su questa pagina possiamo copia incollare il carattere ✪. In altri casi il carattere può essere così speciale da non essere nemmeno correttamente visualizzato, in tali situazioni si può usare una sequenza più complessa in formato \uxxxx come questa:

Descrizione

Sequenza di escape

Risultato a stampa

Esempio stella in cerchio in formato \uxxxx

\u272A

ESERCIZIO: Prova a cercare in google Unicode heart e prova a far stampare a Python un cuoricino , sia copia-incollando direttamente il carattere che usando la notazione \uxxxx

Mostra soluzione
[2]:
# scrivi qui


I ♥ Python, con copia-e-incolla
I ♥ Python, anche nel formato \uxxxx

Le stringhe sono immutabili

Le stringhe sono oggetti immutabili, quindi una volta create non si possono più cambiare. Questo può apparire restrittivo, ma non è poi così tragico, perchè abbiamo comunque a disposizione queste alternative:

  • generare una nuova stringa a partire da stringhe precedenti

  • se abbiamo una variabile a cui abbiamo assegnato una stringa, possiamo assegnare un’altra stringa a quella variabile

Proviamo a generare una nuova stringa a partire da precedenti, per esempio concatendone due con l’operatore +

[46]:
x = 'ciao'
[47]:
y = x + 'mondo'
[48]:
x
[48]:
'ciao'
[49]:
y
[49]:
'ciaomondo'

L’operazione + quando eseguita tra stringhe le attacca creando una NUOVA stringa. Questo significa che l’associazione per x non è affatto cambiata, l’unica vera modifica osservabile è che abbiamo associato la stringa 'ciaomondo alla variabile y. Prova a sincerartene in Python Tutor cliccando ripetutamente sul bottone Next:

[50]:
# ATTENZIONE: per usare la funzione jupman.pytut() di seguito,
# è necessario eseguire prima questa cella con Shift+Invio

# basta eseguirla una volta sola, la trovi presente anche in tutti i fogli nella prima cella

import jupman
[51]:
x = 'ciao'
y = x + 'mondo'

print(x)
print(y)

jupman.pytut()
ciao
ciaomondo
[51]:

Riassegnare variabili

Altre variazioni allo stato della memoria possono essere ottenute riassegnando le variabili, per esempio:

[52]:
x = 'ciao'
[53]:
y = 'mondo'
[54]:
x = y        # assegnamo a x la stessa stringa contenuta in y
[55]:
x
[55]:
'mondo'
[56]:
y
[56]:
'mondo'

Se una stringa che è stata creata non risulta assegnata a nessuna variabile, Python si occuperà automaticamente di eliminarla dalla memoria. Nel caso qui sopra, la stringa ‘ciao’ in sè non è mai cambiata, semplicemente a un certo punto si è ritrovata non più assegnata ad alcuna variabile, e perciò Python ha provveduto ad eliminarla dalla memoria. Guarda cosa succede in Python Tutor:

[57]:
x = 'ciao'
y = 'mondo'
x = y

jupman.pytut()
[57]:

Riassegnare una variabile a sè stessa

Possiamo chiederci cosa succede quando scriviamo qualcosa del genere:

[58]:
x = 'ciao'

x = x
[59]:
print(x)
ciao

Non è successo molto, l’assegnazione di x è rimasta inalterata.

Ma cosa succede se a destra dell’= mettiamo una formula più complessa?

[60]:
x = 'ciao'

x = x + 'mondo'

print(x)
ciaomondo

Cerchiamo di capire bene che è successo.

Nella prima linea, Python ha generato la stringa 'ciao' e l’ha assegnata alla variabile x. Ma fin qui, niente di straordinario.

Poi, nella seconda linea, Python ha fatto due cose:

  1. ha calcolato il risultato dell’espressione x + 'mondo', generando una NUOVA stringa ciaomondo

  2. ha assegnato la stringa appena generata ciaomondo alla variabile x

E’ fondamentale capire bene che in presenza di riassegnamenti avvengono i due passaggi appena citati, che quindi ribadiamo:

  • PRIMA viene calcolato il risultato dell’espressione a destra dell’= (avendo quindi a disposizione il vecchio valore associato a x)

  • POI il risultato viene associato alla variabile a sinistra dell’=.

Se proviamo a guardare in Python Tutor, questo doppio passaggio viene eseguito in un colpo solo:

[61]:
x = 'ciao'
x = x + 'mondo'

jupman.pytut()
[61]:

ESERCIZIO: Scrivi del codice che cambia lo stato della memoria in modo che alla fine risulti la stampa seguente:

z =  Questo
w =  era
x =  un problema
y =  era
s =  Questo era un problema
  • per scrivere il codice, USA SOLO i simboli =,+,z,w,x,y,s E NIENT’ALTRO

  • puoi usare quante linee di codice ritieni opportune

  • puoi usare ogni simbolo quante volte vuoi

Mostra soluzione
[62]:
# queste variabili ti sono date

z = "Questo"
w = 'è'
x = 'un problema'
y = 'era'
s = ' '

# scrivi qui il codice


[63]:
print("z = ", z)
print("w = ", w)
print("x = ", x)
print("y = ", y)
print("s = ", s)
z =  Questo
w =  era
x =  un problema
y =  era
s =  Questo era un problema

Stringhe e numeri

Le stringhe in Python hanno il tipo str:

[64]:
type("ciao mondo")
[64]:
str

Nelle stringhe possiamo inserire dei caratteri che rappresentano cifre:

[65]:
print("Il carattere 5 rappresenta la cifra cinque, il carattere 3 rappresenta la cifra tre")
Il carattere 5 rappresenta la cifra cinque, il carattere 3 rappresenta la cifra tre

Ovviamente possiamo anche costruire una sequenza di cifre, per avere ciò che sembra un numero:

[66]:
print("La sequenza di caratteri 7583 rappresenta il numero settemila cinquecento ottanta tre")
La sequenza di caratteri 7583 rappresenta il numero settemila cinquecento ottanta tre

Detto ciò, possiamo domandarci come si comporta Python quando abbiamo una stringa che contiene solo una sequenza di caratteri che rappresenta un numero, come per esempio '254'

Possiamo usare '254' (che abbiamo scritto come se fosse una stringa) anche come se fosse un numero? Per esempio, possiamo sommarci 3 ?

'254' + 3

---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-29-d39aa62a7e3d> in <module>
----> 1 "254" + 3

TypeError: can only concatenate str (not "int") to str

Come vedi, Python is offende immediatamente, perchè stiamo cercando di mischiare tipi differenti

QUINDI:

  • Scrivendo '254' tra doppi apici creiamo una stringa di tipo str

  • scrivendo 254 creiamo un numero di tipo int

[67]:
type('254')
[67]:
str
[68]:
type(254)
[68]:
int

ATTENZIONE ALLA print !!

Se provi a stampare una stringa che contiene solo cifre, Python la mostrerà senza apici, e questo potrebbe ingannarti riguardo la sua vera natura !!

[69]:
print('254')
254
[70]:
print(254)
254

Solo in Jupyter, per mostrare costanti, variabili o risultati di calcoli, come alternativa alla print puoi immettere direttamente una formula nella cella. In questo caso siamo semplicmente mostrando una costante, e quando è una stringa vedrai degli apici:

[71]:
'254'
[71]:
'254'
[72]:
254
[72]:
254

Lo stesso discorso vale anche per le variabili:

[73]:
x = '254'
[74]:
x
[74]:
'254'
[75]:
y = 254
[76]:
y
[76]:
254

Quindi, solo in Jupyter, quando devi mostrare una costante, una variabile o un calcolo spesso conviene scriverlo direttamente nella cella senza usare la print.

Conversioni - da stringa a numero

Torniamo al problema di sommare '254' + 3. La prima è una stringa, il secondo un numero. Se fossero entrambi numeri la somma sicuramente funzionerebbe:

[77]:
254 + 3
[77]:
257

Quindi possiamo provare a convertire la stringa '254' in un vero intero. Per farlo, possiamo usare int come se fosse una funzione, e passarci come argomento la stringa da convertire:

[78]:
int('254') + 3
[78]:
257

ATTENZIONE: le stringhe e i numeri sono immutabili !!

Questo significa che scrivendo int('254') viene generato un nuovo numero senza intaccare minimamente la stringa '254' da cui si è partiti. Vediamo meglio con un esempio:

[79]:
x = '254'     # assegnamo alla variabile x la stringa '254'
[80]:
y = int(x)    # assegnamo alla variabile y il numero ottenuto convertendo '254' in int
[81]:
x             # la variabile x risulta sempre assegnata alla stringa '254'
[81]:
'254'
[82]:
y             # in y invece adesso c'è un numero (notare che qua non abbiamo apici)
[82]:
254

Può essere utile rivedere l’esempio in Python tutor:

[83]:
x = "254"

y = int(x)

print(y + 3)


jupman.pytut()
257
[83]:

ESERCIZIO: Prova a convertire una stringa che rappresenta un numero malformato (per es un numero con dentro un carattere: '43K12') in un int. Che succede?

[84]:
# scrivi qui


Conversioni - da numero a stringa

Un qualsiasi oggetto può essere convertito a stringa usando str come se fosse una funzione e passandogli l’oggetto da convertire. Proviamo quindi a convertire un numero a stringa:

[85]:
str(5)
[85]:
'5'

notare gli apici nel risultato, che testimoniano che abbiamo effettivamente ottenuto una stringa.

Se per caso vogliamo ottenere una stringa che è la concatenzione di oggetti di tipo diverso dobbiamo stare attenti:

x = 5
s = 'I giorni di lavoro settimanali sono ' + x
print(s)

---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-154-5951bd3aa528> in <module>
      1 x = 5
----> 2 s = 'I giorni di lavoro settimanali sono ' + x
      3 print(s)

TypeError: can only concatenate str (not "int") to str

Un modo di ovviare al problema (anche se non il più comodo) è convertire a stringa ciascuno degli oggetti che usiamo nella concatenazione:

[86]:
x = 3
y = 1.6
s = 'questa settimana ho fatto jogging ' + str(x) + ' volte correndo a una media di ' + str(y) + 'km/h'
print(s)
questa settimana ho fatto jogging 3 volte correndo a una media di 1.6km/h

DOMANDA: Visto quanto detto in precedenza, dopo l’esecuzione del codice nella cella precedente, alla variabile x risulterà associato un numero oppure una stringa ?

Se hai dubbi, usa Python Tutor.

Mostra risposta

Esercizio - stampa lunghezza

Scrivi del codice che data una stringa x, stampa il contenuto della stringa seguito dalla sua lunghezza. Il tuo codice dovrebbe funzionare con qualunque contenuto della variabile x

Esempio - dati:

x = 'jaguar'

Dovrebbe stampare:

jaguar6
Mostra soluzione
[4]:
# scrivi qui


jaguar6

Prosegui

Trovi ulteriori esercizi nel foglio Stringhe 2 - operatori

[ ]: