Speaker:
Repository github per questi tutorial:
Materiale tratto dal libro SoftPython
Esc)Il codice Python si può normalmente trovere in file con estensione:
.py: semplici file di testo, es math.py.ipynb: notebook Jupyter interattivi come questo, che contengono celle con l'outputRiferimenti: SoftPython - Strumenti e script
ATTENZIONE: In questo tutorial usiamo SOLO PYTHON 3
Se per caso ottieni comportamenti inattesi, controlla di usare Python 3 e non il 2. Se per caso il tuo sistema operativo scrivendo python fa partire il 2, prova ad eseguire il tre scrivendo il comando: python3
Scorciatoie da tastiera per utenti Windows e Linux:
Ctrl+InvioShift+InvioAlt+InvioKernel -> RestartSe sei un utente Mac, sostituisci i tasti sopra con i seguenti:
⌘⇧⌥Vediamo brevemente come funzionano i fogli Jupyter.
ESERCIZIO: Proviamo a inserire un comando Python: scrivi nella cella qua sotto l'espressione 3 + 5, e poi mentre sei in quella cella premi i tasti speciali Control+Invio. Un'espressione produce sempre un risultato, in questo caso dovresti vedere apparire il numero 8
ESERCIZIO: in Python possiamo scrivere commenti iniziando una riga con un cancelletto #. Come prima, scrivi nella cella sotto 3 + 5 ma questa volta scrivilo nella riga sotto la scritta # scrivi qui:
ESERCIZIO: Jupyter per ogni cella mostra il risultato solo dell'ultima riga eseguita in quella cella. Prova a inserire questo codice nella cella sotto ed esegui premendo Control+Invio. Che risultato appare?
3 + 5
1 + 1
ESERCIZIO: a) Prova adesso a inserire questo codice nella cella sotto ed esegui premendo Control+Invio. Che risultato appare?
print(3 + 5)
print(1 + 1)
b) E così cosa stamperà?
print(3 + 5)
1 + 1
3 + 4
ESERCIZIO: Proviamo adesso a creare noi una nuova cella.
Mentre sei con il cursore in questa cella, premi Alt+Invio. Si dovrebbe creare una nuova cella dopo la presente.
Nella cella appena creata, inserisci 2 + 3 e poi premi Shift+Invio. Cosa succede al cursore? Prova la differenze con Control+Invio. Se non capisci la differenza, prova a premere ripetutamente Shift+Invio e vedi che succede.
Per creare una variabile è sufficiente assegnarle direttamente un valore
fiori = 5
(volendo potremmo anche dichiarare il tipo ma non è necessario)
Per stampare sequenze di caratteri:
print("La mattina abbiamo raccolto", fiori, "fiori")
La mattina abbiamo raccolto 5 fiori
Per aggiornare delle variabili le puoi riassegnare:
fiori = 5
print("La mattina abbiamo raccolto", fiori, "fiori")
rose_rosse = 3
print("Pomeriggio abbiamo raccolto altre", rose_rosse, "rose")
fiori = fiori + rose_rosse
print("Adesso abbiamo", fiori, "fiori.")
La mattina abbiamo raccolto 5 fiori Pomeriggio abbiamo raccolto altre 3 rose Adesso abbiamo 8 fiori.
Possiamo inizializzare più variabili su una sola linea così separandole con virgole:
libri, quaderni = 3,7
print("Ho comprato", libri, "libri e", quaderni, "quaderni.")
Ho comprato 3 libri e 7 quaderni.
| Tipo | Valore 'vuoto' | Esempio | Altro esempio | Mutabilità | Nota |
|---|---|---|---|---|---|
int |
0 |
3 |
-5 |
immutabili | possono essere arbitrariamente grandi |
float |
0.0 |
3.7 |
-2.3 |
immutabili | numeri in virgola mobile |
bool |
False |
True |
immutabili | ||
str |
"" |
"Buon giorno" |
'come stai?' |
immutabili | |
tuple |
() |
(5, 7, 10, 7) |
("qualcosa", 5, "altro ancora") |
immutabili | |
list |
[] |
[5, 7, 10, 7] |
["qualcosa", 5, "altro ancora"] |
mutabili | |
set |
set() |
{7, 5, 10} |
{"altro ancora", "qualcosa", 5} |
mutabili | |
dict |
{} |
{'limoni':4, 'arance':7} |
{'lampada':'illumina', 'termosifone':'scalda'} |
mutabili | |
NoneType |
None |
Riferimenti: SoftPython, Fondamenti - Tipi di dati
Riferimenti: SoftPython - Tipi di dato - Basi
In Python abbiamo numeri interi:
3 + 5
8
La somma tra interi ovviamente ci da un intero:
type(3 + 5)
int
E se dividiamo interi? Ci troveremo con il tipo in virgola mobile float:
15 / 4
3.75
type(15 / 4)
float
ATTENZIONE al punto !
In Python e in molti formati dati, al posto della nostra virgola si usa il formato inglese con il punto .
15 // 4 # divisione intera
3
I booleani rappresentano valori veri e falsi, e si possono usare per verificare quando certe condizioni avvengono.
Riferimenti
I booleani sono usati nell'algebra booleana e hanno il tipo bool.
I valori di verità sono rappresentati in Python con le parole chiave True e False:
x = True
type(x)
bool
y = False
Possiamo operare sui valori booleani con gli operatori booleani not, and, or:
| a | b | a and b |
|---|---|---|
False |
False |
False |
False |
True |
False |
True |
False |
False |
True |
True |
True |
| a | b | a or b |
|---|---|---|
False |
False |
False |
False |
True |
True |
True |
False |
True |
True |
True |
True |
| a | not a |
|---|---|
False |
True |
True |
False |
Ogni oggetto ha associato un valore logico, e pertanto può essere convertito in un booleano usando bool come una funzione.
In generale, gli oggetti:
FalseTrueOgni tipo di oggetto ha un solo valore considerato 'vuoto'.
Quale sarà il valore 'vuoto' per gli interi?
Che sia il famoso zero 0 ?
bool(0) # Trovato!
False
Tutti gli altri interi essendo considerati 'non vuoti' quando convertiti ci daranno valore logico True:
bool(1)
True
bool(72)
True
bool(-5)
True
Pensiamo alle stringhe.
Quale stringa avrà il valore logico False?
La stringa 'vuota'! Ce n'è una sola:
bool("")
False
Qualunque altra stringa ci darà il valore True:
bool("lampadario")
True
E una stringa di soli spazi " "?
bool(" ")
True
Per fare una conversione verso un tipo di destinazione:
Usa il nome del tipo come se fosse una funzione
Esempio conversione da booleano a intero:
int(True)
1
int(False)
0
Attenzione a:
Gli operatori di comparazione permettono di costruire espressioni che ritornano un valore booleano:
| Comparatore | Descrizione |
|---|---|
a == b |
True se e solo se a = b |
a != b |
True se e solo se a $\neq$ b |
a < b |
True se e solo se a < b |
a > b |
True se e solo se a > b |
a <= b |
True se e solo se a $\leq$ b |
a >= b |
True se e solo se a $\geq$ b |
3 == 3
True
3 == 5
False
3 != 5
True
3 < 5
True
5 <= 5
True
Le comparazioni sono espressioni che producono booleani
-> possiamo anche assegnare il risultato ad una variabile:
x = 5 > 3
print(x)
True
Data un paio di quantità:
x, y = 7, 5
Come verificare se x e y sono entrambe maggiori di zero?
Il modo corretto (per quanto un po' verboso) è il seguente:
x > 0 and y > 0
True
ATTENZIONE: la seguente scrittura invece NON è corretta:
x and y > 0 # SBAGLIATO!
-5 and 3 > 0
True
Python offre diversi operatori per lavorare con le stringhe:
| Operatore | Uso | Risultato | Significato |
|---|---|---|---|
| len | len(str) |
int | Ritorna la lunghezza della stringa |
| concatenazione | str1 + str2 |
str | Concatena due stringhe |
| inclusione | str1 in str2 |
bool | Controlla se la stringa è presente in un'altra stringa |
| indice | str[int] |
str | Legge il carattere all'indice specificato |
| slice | str[int:int] |
str | Estrae una sotto-stringa |
| uguaglianza | ==,!= |
bool |
Controlla se due stringhe sono uguali o differenti |
| replicazione | str * int |
str | Replica la stringa |
Per ottenere la lunghezza di una lista, possiamo usare la funzione len:
len('legna')
5
Una stringa è una sequenza di caratteri
la posizione dei caratteri nella sequenza inizia da 0
Come accedere al carattere in posizione 2?
#0123
'ciao'[2]
'a'
Come leggere solo una sottosequenza che parte da un una posizione ad un'altra?
Basta indicare delle quadre [ ] con:
: come separatore #0123456789
parola = 'mercantile'
estratta = parola[3:8]
estratta
'canti'
parola
'mercantile'
NOTA: la stringa estratta è completamente NUOVA e slegata dall'originale:
#0123456789
parola = 'mercantile'
estratta = parola[3:8]
parola = "peschereccio"
print(estratta)
canti
Una delle cose che si fanno più frequentemente è concatenare delle stringhe:
"ciao " + "mondo"
'ciao mondo'
Attenzione a quando concateniamo una stringa e un numero
"ciao " + 7
Python si arrabbia:
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
<ipython-input-38-e219e8205f7d> in <module>()
----> 1 "ciao " + 7
TypeError: Can't convert 'int' object to str implicitly
Bisogna convertire esplicitamente il numero (in genere, qualunque oggetto) in una stringa
Per concatenerare oggetti che non sono stringhe:
Modo 1: usare la funzione str come qui:
"ciao " + str(7)
'ciao 7'
Modo 2 (meglio): usare l'operatore di formattazione percentuale %
%s quello che mettete dopo un % dopo la stringa"ciao %s" % 7
'ciao 7'
%s può stare all'interno della stringa e venire ripetuto.
Per ogni occorrenza si può passare un sostituto diverso, come per esempio nella tupla ("bello", "Python")
"Che %s finalmente imparo %s" % ("bello", "Python")
'Che bello finalmente imparo Python'
Modo 3 (il migliore) le f-string si costruiscono anteponendo f alla stringa e inserendo dentro la stringa delle graffe con le espressioni di cui vogliamo vedere il risultato.
x = 3
y = 5
s = "Fantastico"
# Nelle stringhe di formattazione possiamo mettere...
print( f"Metto variabili: {x} e anche espressioni: {x + y}. {s}!" )
Metto variabili: 3 e anche espressioni: 8. Fantastico!
Le stringhe sono immutabili...
...quindi tentare di sovrascrivere un carattere porta ad un errore:
#01234
s = 'ciao'
s[2] = 'b' # SBAGLIATO!
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
<ipython-input-113-e5847c6fa4bf> in <module>
----> 1 s[2] = 'b'
TypeError: 'str' object does not support item assignment
Quello che si può fare è cambiare l'associazione della variabile
Generiamo una nuova stringa prendendo pezzi dall'originale:
s = 'ciao'
s = s[0] + s[1] + 'b' + s[3]
s
'cibo'
Il vecchio oggetto 'ciao' non essendo più raggiungibile da nessuna variabile, prima o poi verrà automaticamente marcato da Python come oggetto eliminabile dalla memoria tramite la cosiddetta garbage collection.
In Python quasi tutto è un oggetto
Ogni tipo di oggetto ha delle azioni chiamati metodi che si possono eseguire su quello oggetto
Per esempio, ogni stringa è un oggetto di tipo str
| Metodo | Risultato | Significato |
|---|---|---|
| str.upper() | str | Ritorna la stringa con tutti i caratteri maiuscoli |
| str.lower() | str | Ritorna la stringa con tutti i caratteri minuscoli |
| str.capitalize() | str | Ritorna la stringa con il primo carattere maiuscolo |
| str1.startswith(str2) | bool | Controlla se la stringa inizia con un'altra |
| str1.endswith(str2) | bool | Controlla se la stringa finisce con un'altra |
| str1.isalpha(str2) | bool | Controlla se tutti i caratteri sono alfabetici |
| str1.isdigit(str2) | bool | Controlla se tutti i caratteri sono cifre |
| str.isupper() | bool | Controlla se tutti i caratteri sono minuscoli |
| str.islower() | bool | Controlla se tutti i caratteri sono maiuscoli |
Riferimenti: SoftPython - Stringhe 3
Data una stringa che rappresenta un nome come "trento"...
quale metodo potremmo usare per rendere in maiuscolo la prima lettera?
Proviamo il metodo esistente capitalize()
(nota: la stringa è tutta in minuscolo e capital in inglese vuol anche dire 'maiuscolo' )
"trento".capitalize()
'Trento'
| Metodo | Risultato | Significato |
|---|---|---|
| str1.strip(str2) | str | Rimuove stringhe dai lati |
| str1.lstrip(str2) | str | Rimuove stringhe da sinistra |
| str1.rstrip(str2) | str | Rimuove stringhe da destra |
| str1.count(str2) | int | Conta il numero di occorrenze di una sottostringa |
| str1.find(str2) | int | Ritorna la prima posizione di una sottostringa a partire da sinistra |
| str1.rfind(str2) | int | Ritorna la prima posizione di una sottostringa a partire da destra |
| str1.replace(str2, str3) | str | Sostituisce sottostringhe |
Riferimenti: SoftPython - Stringhe 4
ATTENZIONE: i metodi delle stringhe generano stringhe SEMPRE NUOVE
L’oggetto stringa originale non viene MAI modificato.
originale = "PARLARE E BRINDARE"
risultato = originale.replace('ARE', 'IAMO')
risultato
'PARLIAMO E BRINDIAMO'
originale
'PARLARE E BRINDARE'
Una lista in python è una sequenza mutabile di elementi eterogenei, in cui possiamo mettere gli oggetti che vogliamo.
Riferimenti - SoftPython:
Creiamo una lista di stringhe:
lista = ["ciao", "soft", "python"]
lista
['ciao', 'soft', 'python']
Le liste sono sequenze di oggetti possibilmente eterogenei...
quindi dentro ci potete buttare di tutto, interi, stringhe, duplicati, altre liste, ...:
cose = ["ciao", 97, "ciao", ["a","b"] ]
cose
['ciao', 97, 'ciao', ['a', 'b']]
Per manipolare le liste vi sono diversi operatori. I seguenti si comportano come quelli visti per le stringhe.
| Operatore | Use | Risultato | Significato |
|---|---|---|---|
| len | len(lst) |
int |
Ritorna la lunghezza di una lista |
| indice | list[int] |
obj | Legge/scrive un elemento all'indice specificato |
| slice | list[int:int] |
list |
Estrae una sotto-lista - ritorna una NUOVA lista |
| inclusione | obj in list |
bool |
Controlla se un elemento è presente in una lista |
| concatenazione | list + list |
list |
Concatena due liste - ritorna una NUOVA lista |
| aggregazione | max(lst) |
int |
Data una lista di numeri, ritorna il massimo |
| aggregazione | min(lst) |
int |
Data una lista di numeri, ritorna il minimo |
| aggregazione | sum(lst) |
int |
Data una lista di numeri, li somma tutti |
| replicazione | list * int |
list |
Replica la lista - ritorna una NUOVA lista |
| uguaglianza | ==,!= |
bool |
Controlla se due liste sono uguali o differenti |
Riferimenti: SoftPython - liste 2
Per accedere ad un elemento usiamo un indice (come per per le stringhe):
# 0 1 2
lista = ["ciao", "soft", "python"]
lista[1]
'soft'
In una lista possiamo MODIFICARE le celle con l'assegnazione:
lista[1] = "SOFT"
lista
['ciao', 'SOFT', 'python']
Possiamo estrarre sottosequenze con le slice, come per le stringhe:
# 0 1 2 3 4 5 6 7 8 9
la = [40,30,90,80,60,10,40,20,50,60]
lb = la[3:7]
print(lb)
[80, 60, 10, 40]
ATTENZIONE: l'estrazione produce una NUOVA lista
se modifichiamo l'originale non vedremo alcun cambiamento nella stringa estratta:
la[3] = 999
print(la)
[40, 30, 90, 999, 60, 10, 40, 20, 50, 60]
print(lb)
[80, 60, 10, 40]
| Metodo | Ritorna | Descrizione |
|---|---|---|
| list.append(object) | None |
Aggiunge un nuovo elemento alla fine della lista |
| list.extend(list) | None |
Aggiunge diversi nuovi elementi alla fine della lista |
| list.insert(int,object) | None |
Aggiunge un nuovo elemento a qualche posizione data |
| list.pop() | object |
Rimuove e ritorna l'elemento all'ultima posizione |
| list.pop(int) | object |
Dato un indice, rimuove e ritorna l'elemento a quella posizione |
| list.reverse() | None |
Inverte l'ordine degli elementi |
| list.sort() | None |
Ordina gli elementi |
| "sep".join(seq) | str |
produce una stringa concatenando tutti gli elementi in seq separati da "sep" |
Riferimenti: SoftPython - liste 3
I METODI DELLE LISTE MODIFICANO LA LISTA SU CUI VENGONO CHIAMATI !
Quando chiami un metodo di una lista (l'oggetto a sinistra del punto .), MODIFICHI la lista stessa (diversamente dai metodi sulle stringhe che generano sempre una nuova stringa senza cambiare l'originale)
ATTENZIONE: I METODI DELLE LISTE NON RITORNANO NULLA!
Quasi sempre ritornano l'oggetto None (diversamente da quelli delle stringhe che ritornano sempre una nuova stringa)
Possiamo aggiungere elementi alla fine di una lista usando il comando append:
parole = []
parole.append("ciao")
parole
['ciao']
parole.append("soft")
parole.append("python")
parole
['ciao', 'soft', 'python']
Le liste si possono ordinare comodamente con il metodo .sort
Proviamo i numeri:
lista = [ 8, 2, 4]
lista.sort()
lista
[2, 4, 8]
Proviamo ad ordinare delle stringhe:
parole = [ 'mondo', 'python', 'ciao',]
parole.sort()
parole
['ciao', 'mondo', 'python']
Per generare una nuova lista invece di modificare l'originale, c'è sorted()
NOTA: sorted è una funzione, non un metodo:
parole = [ 'mondo', 'python', 'ciao',]
sorted(parole)
['ciao', 'mondo', 'python']
# la lista originale non è cambiata:
parole
['mondo', 'python', 'ciao']
Ordine rovesciato
Possiamo indicare in fondo il parametro opzionale reverse e il suo valore, che in questo caso sarà True:
sorted(['mondo', 'python', 'ciao'], reverse=True)
['python', 'mondo', 'ciao']
Rovesciare liste non ordinate
E se volessimo rovesciare una lista così com'è, senza ordinarla in senso decrescente, per esempio per passare da[6,2,4] a [2,4,6]?
Cercando nella libreria di Python,troviamo una comoda funzione reversed() che prende come paramatro la lista che vogliamo rovesciare e ne genera una nuova rovesciata:
reversed([6,2,4])
<list_reverseiterator at 0x7f47b8f59290>
Problema: reversed produce una sequenza 'congelate', che va materializzata convertendola esplicitamente a lista così:
list( reversed([6,2,4]) )
[4, 2, 6]
| Metodo | Ritorna | Descrizione |
|---|---|---|
| list.count(object) | int |
Conta le occorrenze di un elemento |
| list.index(object) | int |
Trova la prima occorrenza di un elemento e ne ritorna la posizione |
| list.remove(object) | None |
Rimuove la prima occorrenza di un elemento |
| str1.split(str2) | list |
Produce una lista con tutte le parole in str1 separate da str2 |
ATTENZIONE: spesso questi metodi vengono abusati portando a codice incorretto / inefficiente, usali con giudizio!
Riferimenti: SoftPython - liste 4
Una tupla in Python è una sequenza immutabile di elementi eterogenei che ammette duplicati
Le tuple si creano con le parentesi tonde () e separando gli elementi da virgole ,.
Qualche esempio:
numeri = (6,7,5,7,7,9)
print(numeri)
(6, 7, 5, 7, 7, 9)
roba = (4, "carta", 5, 2,"scatole", 7) # tupla eterogenea
EVITA di mettere oggetti mutabili dentro le tuple!
Per creare una tupla di un solo elemento: aggiungi una virgola dopo l'ultimo elemento:
tuplina = (4,) # occhio alla virgola !!!
type(tuplina)
tuple
Per vedere la differenza, scriviamo qua sotto (4) senza virgola:
farlocca = (4)
type(farlocca)
int
Vediamo che farlocca è un int...
4 è stato valutato come un'espressione dentro delle tonde e il risultato è il contenuto delle tonde!vuota = ()
print(vuota)
()
type(vuota)
tuple
Per assegnare dei valori a delle variabili è possibile usare una notazione del genere,
in cui a sinistra dell' = mettiamo nomi di variabili e a destra una sequenza di valori:
a,b,c = 1, 2, 3
b
2
Se ci chiediamo cosa sia quel 1,2,3, possiamo provare a mettere a sinistra solo una variabile:
# ATTENZIONE: MEGLIO EVITARE !
x = 1,2,3
type(x)
tuple
Vediamo che Python ha considerato quel 1,2,3 come una tupla.
Attenzione: Se trovi strane tuple durante l'esecuzione, cerca virgole extra!
stringa_farlocca = "ciao", # OCCHIO
stringa_farlocca
('ciao',)
Puoi creare una tupla da una qualsiasi sequenza, per esempio da una lista:
tuple( [8,2,5] )
(8, 2, 5)
list( (3,4,2,3) ) # viceversa
[3, 4, 2, 3]
I seguenti operatori funzionano sulle tuple e si comportano esattamente come per le liste:
| Operatore | Esempio | Risultato | Significato |
|---|---|---|---|
| lunghezza | len(tuple) |
int |
Ritorna la lunghezza di una tupla |
| indice | tuple[int] |
object |
Legge un elemento all'indice specificato |
| slice | tuple[int:int] |
tuple |
Estrae una sotto-tupla - ritorna una NUOVA tupla |
| concatenazione | tuple1 + tuple2 |
tuple |
Concatena due tuple - ritorna una NUOVA tupla |
| appartenenza | object in tuple |
bool |
Controlla se un elemento è presente in una tupla |
| replicazione | tuple * int |
tuple |
Replica la tupla - ritorna una NUOVA tupla |
| uguaglianza | ==,!= |
bool |
Controlla se due tuple sono uguali o differenti |
Riferimento: SoftPython - Tuple
s = {'b','a','d','c'}
type(s)
set
s = {'b','a','d','c'}
print(s)
{'d', 'a', 'b', 'c'}
ATTENZIONE: L'ORDINE NEGLI INSIEMI *NON* E' GARANTITO!
*NON* CREDERE A QUELLO CHE VEDI !!
L'ordine in cui è stata effettuata la stampa è diverso da quello con cui abbiamo costruito l'insieme - potrebbe anche variare a seconda della versione di Python.
Attenzione a cosa succede se proviamo a chiedere a Jupyter di mostrarci il contenuto dell'insieme, scrivendo solo la variabile s SENZA la print:
s
{'a', 'b', 'c', 'd'}
Adesso appare in ordine alfabetico !
Motivo: Jupyter per mostrare le variabili invece della print normale stampa implicitamente con la pprint (pretty print), che SOLO per gli insiemi ci fa la cortesia di ordinare il risultato prima di stamparlo.
Gli insiemi sono utili per rimuovere duplicati da una sequenza
Come per liste e stringhe, possiamo creare un set a partire da un'altra sequenza:
set('acacia') # da stringa
{'a', 'c', 'i'}
set( [1,2,3,1,2,1,2,1,3,1] ) # da lista
{1, 2, 3}
Indice degli elementi: con gli insiemi NON è possibile ricavare un elemento a partire da un indice:
s[0]
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
<ipython-input-352-c9c96910e542> in <module>
----> 1 s[0]
TypeError: 'set' object is not subscriptable
Per creare un insieme vuoto dobbiamo chiamare la funzione set():
s = set()
ATTENZIONE: Se scrivi {} otterrai un dizionario, NON un insieme !!!
| Operatore | Esempio | Risultato | Descrizione |
|---|---|---|---|
| lunghezza | len(set) |
int |
il numero di elementi nel set |
| appartenenza | el in set |
bool |
verifica se elemento è contenuto nel set |
| unione | set | set |
set |
crea un NUOVO set |
| intersezione | set & set |
set |
crea un NUOVO set |
| differenza | set - set |
set |
crea un NUOVO set |
| differenza simmetrica | set ^ set |
set |
crea un NUOVO set |
| uguaglianza | ==,!= |
bool |
Controlla se due insiemi sono uguali o differenti |
Riferimento: SoftPython - Insiemi
Per verificare se un elemento IMMUTABILE è contenuto in un insieme possiamo usare l'operatore in che ci ritorna un valore booleano:
'a' in {'m','e','n','t','a'}
True
in NEGLI INSIEMI E' UN'OPERAZIONE MOLTO VELOCE
A differenza di liste e tuple, negli insiemi la velocità dell'operatore in NON dipende dalla dimensione della collezione
ATTENZIONE: Cercare elementi mutabili (es liste) in insiemi non è consentito:
['e','f'] in { ('c','d'), ('a','b')}
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
/tmp/ipykernel_29295/1711245333.py in <module>
----> 1 ['a','b'] in { ('c','d'), ('a','b'), ('e','f') }
TypeError: unhashable type: 'list'
('e','f') in { ('c','d'), ('a','b') } # una tupla invece è immutabile quindi possiamo cercarla
False
Per verificare la non appartenza, ci sono due forme:
"carota" not in {"anguria","banana","mela"}
True
not "carota" in {"anguria", "banana", "mela"}
True
Vi sono metodi analoghi agli operatori |, &, -, ^ che creano un NUOVO set.
NOTA: diversamente dagli operatori, questi metodi accettano come parametro una qualsiasi sequenza, non solo insiemi:
| Metodo | Risultato | Descrizione | Operatore analogo |
|---|---|---|---|
set.union(seq) |
set |
unione, crea un NUOVO set | | |
set.intersection(seq) |
set |
intersezione, crea un NUOVO set | & |
set.difference(seq) |
set |
differenza, crea un NUOVO set | - |
set.symmetric_difference(seq) |
set |
differenza simmetrica, crea un NUOVO set | ^ |
Metodi che MODIFICANO il primo insieme su cui sono chiamati (e ritornano None!):
| Metodo | Risultato | Descrizione |
|---|---|---|
setA.update(setB) |
None |
unione, MODIFICA setA |
setA.intersection_update(setB) |
None |
intersezione, MODIFICA setA |
setA.difference_update(setB) |
None |
differenza, MODIFICA setA |
setA.symmetric_difference_update(setB) |
None |
differenza simmetrica, MODIFICA setA |
Riferimenti: SoftPython - Insiemi
I dizionari sono dei contenitori mutabili che consentono di abbinare dei valori a delle voci dette chiavi.
Riferimenti:
| Operatore | Esempio | Ritorna | Descrizione |
|---|---|---|---|
| lunghezza | len(dict) |
int |
Ritorna il numero di chiavi |
| indice | dict[chiave] |
obj | Ritorna il valore associato alla chiave |
| modifica | dict[chiave] = valore |
Aggiunge o modifica il valore associato ad una chiave | |
| rimozione | del dict[chiave] |
Rimuove la coppia chiave/valore | |
| appartenenza | chiave in dict |
bool |
Ritorna True se chiave è presente nel dizionario |
| uguaglianza | ==,!= |
bool |
Controlla se due dizionari sono uguali o differenti |
Riferimenti: SoftPython - Dizionari 2
Possiamo creare un dizionario con
{ }:,d = { 'sedia' : 'un mobile per sedersi',
'armadio' : 'un mobile a ripiani',
}
Nota:
Per accedere ai valori, possiamo usare le chiavi tra parentesi quadre:
d = { 'sedia' : 'un mobile per sedersi',
'armadio' : 'un mobile a ripiani',
}
d['sedia']
'un mobile per sedersi'
d['armadio']
'un mobile a ripiani'
Possiamo aggiungere un'associazione così:
d['lampadario'] = 'un apparecchio di illuminazione'
d
{'sedia': 'un mobile per sedersi',
'armadio': 'un mobile a ripiani',
'lampadario': 'un apparecchio di illuminazione'}
si può anche usare sovrascrivere le precedenti:
d['armadio'] = 'un mobile a ripiani, solitamente due ante'
d
{'sedia': 'un mobile per sedersi',
'armadio': 'un mobile a ripiani, solitamente due ante',
'lampadario': 'un apparecchio di illuminazione'}
Come valori nei dizionari possiamo mettere quello che ci pare, numeri, stringhe, tuple, liste, altri dizionari ..
ingredienti = { 'farina' : 500,
'uova' : 2,
'zucchero' : 200,
}
satelliti = {
'Marte' : ['Phobos','Deimos'],
'Saturno' : ['Titano','Hyperion', 'Mimas', 'Enceladus', 'Dione','Rhea'],
}
d = {}
d[123] = 'ammissibile'
d['una stringa'] = 'ok'
d[ ('oppure','una','tupla') ] = 'va bene'
d
{123: 'ammissibile',
'una stringa': 'ok',
('oppure', 'una', 'tupla'): 'va bene'}
Cosa succede se tentiamo di usare tipi mutabili?
d[ ['io', 'sono', 'una', 'lista'] ] = "OCCHIO!"
TypeError Traceback (most recent call last)
/tmp/ipykernel_3047/3187326270.py in <module>
----> 1 d[ ['io', 'sono', 'una', 'lista'] ] = "OCCHIO!"
TypeError: unhashable type: 'list'
Per sapere se una chiave è contenuta in un dizionario, possiamo usare l'operatore in.
ATTENZIONE: in nei dizionari cerca solo nelle chiavi!
ingredienti = { 'farina' : 500,
'uova' : 2,
'zucchero' : 200,
}
'farina' in ingredienti
True
500 in ingredienti
False
| Metodo | Ritorna | Descrizione |
|---|---|---|
| dict.keys() | dict_keys |
Ritorna una vista di chiavi che sono presenti nel dizionario |
| dict.values() | dict_values |
Ritorna una vista di valori presenti nel dizionario |
| dict.items() | dict_items |
Ritorna una vista di coppie (chiave, valore) presenti nel dizionario |
| d1.update(d2) | None |
MODIFICA il dizionario diz1 con le coppie chiave / valore trovate in diz2 |
ATTENZIONE: i metodi keys, values e items restituiscono viste immutabili e sono spesso causa di fraintendimenti e/o codice inefficiente. Se ti senti nella necessità di usarli, chiediti sempre se è possibile risolvere il problema usando solo gli operatori.
Riferimenti: SoftPython - dizionari 3
Se vogliamo copiare una struttura dati mutabili, abbiamo a disposizione il metodo .copy()
.copy effettua solo una cosiddetta copia in superficie (shallow copy)
per la copia in profondità (deep copy) servono altri sistemi!
listonaA = [ ['Fate', 'attenzione'],
['a', 'dove'],
['puntano', 'le', 'frecce']
]
print(listonaA)
[['Fate', 'attenzione'], ['a', 'dove'], ['puntano', 'le', 'frecce']]
Proviamo a visualizzare il codice in Python Tutor:
Proviamo adesso a fare una copia con il metodo .copy():
listonaA = [ ['Fate', 'attenzione'],
['a', 'dove'],
['puntano', 'le', 'frecce']
]
listonaB = listonaA.copy() # copia *in superficie*
print(listonaA)
print(listonaB)
[['Fate', 'attenzione'], ['a', 'dove'], ['puntano', 'le', 'frecce']] [['Fate', 'attenzione'], ['a', 'dove'], ['puntano', 'le', 'frecce']]
Notiamo che abbiamo due listone le cui celle puntano a delle sottoliste condivise, quindi scrivendo in una sotto cella di listonaA di fatto finiamo anche per scrivere in listonaB!
listonaA = [ ['Fate', 'attenzione'],
['a', 'dove'],
['puntano', 'le', 'frecce']
]
listonaB = listonaA.copy() # copia *in superficie*
listonaA[2][0] = 'OCCHIO!' # cella con 'frecce'
print(listonaA)
print(listonaB)
[['Fate', 'attenzione'], ['a', 'dove'], ['OCCHIO!', 'le', 'frecce']] [['Fate', 'attenzione'], ['a', 'dove'], ['OCCHIO!', 'le', 'frecce']]
Per rimediare possiamo usare la cosidetta copia in profondità (deep copy) prima importando il modulo copy e poi chiamando la sua funzione deepcopy e passandogli come parametro listonaA:
import copy # MODULO PYTHON
listonaA = [ ['Fate', 'attenzione'],
['a', 'dove'],
['puntano', 'le', 'frecce']
]
listonaB = copy.deepcopy(listonaA)
listonaA[2][0] = 'OCCHIO!' # cella con 'frecce'
print(listonaA)
print(listonaB)
[['Fate', 'attenzione'], ['a', 'dove'], ['OCCHIO!', 'le', 'frecce']] [['Fate', 'attenzione'], ['a', 'dove'], ['puntano', 'le', 'frecce']]
Con copy.deepcopy abbiamo veramente strutture dati completamente distinte:
✪ Ci è stato inviato un testo illegale, immorale e che fa pure ingrassare. Per tutelare la pubblica salute abbiamo l'arduo compito di censurarlo e renderlo consono al buon costume.
parole_malefiche con una più salubre censura, trasformando il testo in modo che la print di testo_censurato non contenga nessuna parola incriminata.Esempio:
testo= "Grazie all'uso di Cera Splendent tutto brilla!"
parola_malefica = "splendent"
censura = "******"
testo_censurato: "Grazie all'uso di Cera ****** tutto brilla!"
"Censurata 1 parola"
testo = """Ed è proprio da questa portentosa crema che nasce la crema
al mascarpone base del tiramisù, prima classificata al premio Crema
dell'Anno insieme alla nutella. Il dolce italiano per eccellenza,
quello più famoso e amato, ma soprattutto che ha dato vita a
tantissime altre versioni, anche tiramisù senza uova! Poi il Tiramisù
alle fragole o quello alla Nutella, giusto per citarne un paio!
Senza contare le rivisitazioni più raffinate come la crostata morbida
o la torta al tiramisù.
"""
parola_malefica1 = "Tiramisù"
parola_malefica2 = "nutella"
censura = "******"
testo_censurato = ''
# scrivi qui
✪✪ Requisiti: liste
Data una stringa parola, creare una NUOVA lista che contenga la parola seguita da sè stessa rovesciata
Esempio - dato:
parola = "cantina"
deve stampare:
['c', 'a', 'n', 't', 'i', 'n', 'a', 'n', 'i', 't', 'n', 'a', 'c']
parola = "cantina" #['c','a','n','t','i','n','a','n','i','t','n','a','c']
#parola = "vino" # ['v', 'i', 'n', 'o', 'n', 'i', 'v']
#parola = "ok" # ['o', 'k', 'o']
# scrivi qui
✪ Requisiti: dizionari
Al tranquillissimo paesino di Gerontonia vi sono delle coppie assai tenaci che dopo 75 anni dal fatico "Sì!" meritano di festeggiare le nozze di platino. Abbiamo una lista dei matrimoni con esattamente 3 coppie scritte nel formato "maschio-femmina", e vogliamo creare un dizionario diz che associa ad ogni maschio la corrispondente compagna.
Esempio - data:
matrimoni = ["Amilcare-Maria Eusonia", "Oronzo Pio-Genoveffa", "Venceslao-Elvira"]
dopo il tuo codice, deve risultare:
>>> print(diz)
{'Amilcare' : 'Maria Eusonia',
'Oronzo Pio' : 'Genoveffa',
'Venceslao' : 'Elvira'}
matrimoni = ["Amilcare-Maria Eusonia", "Oronzo Pio-Genoveffa", "Venceslao-Elvira"]
#matrimoni = ["Liutprando-Brunilde", "Clodoveo-Elvira Pancrazia Ludmilla",
# "Gian Evaristo-Ubalda"]
# scrivi qui