Insiemi
Scarica zip esercizi
Un insieme è una collezione mutabile senza ordine di elementi immutabili e distinti (cioè senza duplicati). Il tipo di dati in Python per rappresentare gli insiemi si chiama set
.
Che fare
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
sets1.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.
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 un insieme
Possiamo creare un insieme usando le parentesi graffe, e separando gli elementi da virgole ,
Proviamo un insieme di caratteri:
[2]:
s = {'b','a','d','c'}
[3]:
type(s)
[3]:
set
ATTENZIONE: GLI INSIEMI *NON* SONO ORDINATI !!!
NON CREDERE A QUELLO CHE VEDI !!
Proviamo a stampare l’insieme:
[4]:
print(s)
{'c', 'b', 'a', 'd'}
Come vedi, l’ordine in cui è stata effettuata la stampa è diverso da quello con cui abbiamo costruito l’insieme. A seconda della versione di Python che stai usando, sul tuo computer potrebbe essere diverso ancora!!
Questo perchè l’ordine negli insiemi NON è garantito: l’unica cosa che conta è se un elemento appartiene ad un insieme oppure no.
Come ulteriore dimostrazione, possiamo chiedere a Jupyter di mostrarci il contenuto dell’insieme, scrivendo solo la variabile s
SENZA la print
:
[5]:
s
[5]:
{'a', 'b', 'c', 'd'}
Adesso appare in ordine alfabetico ! Succede così perchè Jupyter quando mostra le variabili le stampa implicitamente non con la print
ma con la pprint (pretty print), che SOLO per gli insiemi ci fa la cortesia di ordinare il risultato prima di stamparlo. Possiamo ringraziare, ma non lasciamo che ci confonda !!
Indice degli elementi: visto che gli insiemi non hanno ordine, chiedere a Python di estrarre un elemento ad una certa posizione non avrebbe senso. Quindi, diversamente da stringhe, liste e tuple, 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
Abbiamo detto che un insieme ha solo elementi distinti, cioè senza duplicati - che succede se proviamo a metterli comunque ?
[6]:
s = {6,7,5,9,5,5,7}
[7]:
s
[7]:
{5, 6, 7, 9}
Notiamo che Python ha silenziosamente rimosso i duplicati.
Convertire sequenze in insiemi
Come per liste e stringhe, possiamo creare un set
a partire da un’altra sequenza:
[8]:
set('acacia') # da stringa
[8]:
{'a', 'c', 'i'}
[9]:
set( [1,2,3,1,2,1,2,1,3,1] ) # da lista
[9]:
{1, 2, 3}
[10]:
set( (4,6,1,5,1,4,1,5,4,5) ) # da tupla
[10]:
{1, 4, 5, 6}
Di nuovo, notiamo come nell’insieme creato non siano presenti duplicati.
RICORDATI: Gli insiemi sono utili per rimuovere duplicati da una sequenza
Elementi mutabili e hash
Rivediamo la definizione di insieme data all’inizio:
Un insieme è una collezione mutabile senza ordine di elementi immutabili e distinti
Finora abbiamo creato l’insieme solo usando elementi immutabili come numeri e stringhe.
Cosa succede se mettiamo degli elementi mutabili, come liste?
>>> s = { [1,2,3], [4,5] }
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
<ipython-input-40-a6c538692ccb> in <module>
----> 1 s = { [1,2,3], [4,5] }
TypeError: unhashable type: 'list'
Otteniamo TypeError: unhashable type: 'list'
, che letteralmente significa che Python non è riuscito a calcolare lo spezzatino (hash) della lista. Cosa sarà mai questa particolare pietanza??
Cos’è lo hash? Lo hash di un oggetto è un numero che Python può associargli, per esempio puoi vedere lo hash
di un oggetto con l’omonima funzione:
[11]:
hash( "Questa è una bella giornata" ) # stringa
[11]:
8459839086718867122
[12]:
hash( 111112222223333333344444445555555555 ) # numero
[12]:
651300278308214397
Immagina che lo hash sia una specie di etichetta con queste caratteristiche:
è troppo breve per descrivere completamente l’oggetto a cui è associata (tradotto: data solo un’etichetta hash, non puoi ricostruire l’oggetto che rappresenta)
è abbastanza lunga per identificare quasi univocamente l’oggetto…
… anche se al mondo potrebbero esistere oggetti diversi hanno però associata esattamente la stessa etichetta
Cosa c’entra con i nostri insiemi? Lo hash ha vari utilizzi, ma tipicamente Python lo usa per ritrovare velocemente un’oggetto in collezioni basate sugli hash, come gli insiemi e i dizionari. Quanto velocemente? Parecchio: anche con insiemi enormi, otteniamo una risposta sempre in un tempo costante e brevissimo! In altre parole, la velocità di risposta non dipende dalla dimensione dell’insieme (salvo casi patologici).
Questa velocità è consentita dal fatto che dato un oggetto da cercare, Python è in grado di ricavare velocemente la sua etichetta hash: poi con l’etichetta in mano, riesce a individuare nel magazzino della memoria molto in fretta se vi sono oggetti che hanno la stessa etichetta. Se vengono trovati, saranno quasi sicuramente molto pochi, e basterà quindi confrontarli con quello cercato.
Gli oggetti *immutabili* hanno sempre lo stessa etichetta hash da quando sono creati fino alla fine del programma. Quelli mutabili invece no: ogni volta che li cambiamo, viene anche automaticamente cambiato l’hash. Immaginati un supermercato dove i commessi dispongono gli alimentari in base all’etichetta separando per esempio il caffè nello scaffale per la prima colazione e la varechina nello scaffale dei detersivi. Se sei un cliente e vuoi il caffè, guardi i cartelli e ti dirigi subito verso lo scaffale della prima colazione. Immagina cosa succederebbe se un mago malvagio potesse trasmutare gli oggetti già collocati negli scaffali in altri oggetti, quindi per esempio il caffè in varechina (assumiamo che al momento della trasmutazione oltre al caffè cambi anche l’etichetta hash). Sicuramente porterebbe tanta confusione, e se non si sta attenti, anche un gran mal di pancia.
Quindi per offrirti il vantaggio della ricerca rapida evitando situazioni disastrose, Python ti impone di collocare nell’insieme solo oggetti con hash stabile, cioè gli oggetti immutabili.
DOMANDA: Possiamo inserire una tupla dentro un insieme? Prova a verificare la tua supposizione con un esempio di codice.
Mostra rispostaInsieme vuoto
ATTENZIONE: Se scrivi {}
otterrai un dizionario, NON un insieme !!!
Per creare un insieme vuoto dobbiamo chiamare la funzione set()
:
[13]:
s = set()
[14]:
s
[14]:
set()
ESERCIZIO: prova a scrivere nella cella qua sotto {}
e guarda il tipo dell’oggetto ottenuto con type
[15]:
# scrivi qui
DOMANDA: Possiamo inserire un insieme dentro un’altro insieme? Guarda bene la definizione di insieme, poi verifica le tuo supposizioni provando a scrivere del codice per creare un insieme che abbia dentro un’altro insieme.
ATTENZIONE: Per fare la verifica, NON usare la funzione set
, usa solo creazione con parentesi graffe
DOMANDA: Se scriviamo una cosa del genere, cosa otterremo? (attento !)
set(set(['a','b']))
un insieme con dentro
'a'
e'b'
un insieme con dentro un insieme contenente gli elementi
'a'
e'b'
un errore (quale?)
DOMANDA: Guarda le seguenti espressioni, e per ciascuna cerca di indovinare quale risultato producono (o se danno errore):
{'oh','la','la'}
set([3,4,2,3,2,2,2,-1])
{(1,2),(2,3)}
set('aba')
str({'a'})
{1;2;3}
set( 1,2,3 )
set( {1,2,3} )
set( [1,2,3] )
set( (1,2,3) )
set( "abc" )
set( "1232" )
set( [ {1,2,3,2} ] )
set( [ [1,2,3,2] ] )
set( [ (1,2,3,2) ] )
set( [ "abcb" ] )
set( [ "1232" ] )
set((1,2,3,2))
set([(),()])
set([])
set(list(set()))
Esercizio: dedup
Scrivi del codice breve per creare una lista lb
che contiene tutti gli elementi dalla lista la
senza duplicati e ordinati alfabeticamente.
NON DEVE cambiare la lista originale
la
NON usare cicli
il tuo codice dovrebbe funzionare con qualunque
la
la = ['c','a','b','c','d','b','e']
dopo il tuo codice, dovresti ottenere:
>>> print(la)
['c', 'a', 'b', 'c', 'd', 'b', 'e']
>>> print(lb)
['a', 'b', 'c', 'd', 'e']
[16]:
la = ['c','a','b','c','d','b','e']
# scrivi qui
la = ['c', 'a', 'b', 'c', 'd', 'b', 'e']
lb = ['a', 'b', 'c', 'd', 'e']
Frozenset
INFO: questo argomento è opzionale ai fini della comprensione del libro
In Python esistono anche insiemi immutabili che si chiamano frozenset
. Qui ci limitamo a ricordare che i frozenset
essendo immutabili hanno un’etichetta hash associata e possono essere inseriti come elementi di altri insiemi. Per il resto rimandiamo alla documentazione ufficiale.
Operatori
Operatore |
Esempio |
Risultato |
Descrizione |
---|---|---|---|
|
|
il numero di elementi nel set |
|
object |
|
verifica se elemento è contenuto nel set |
|
set | set |
|
crea un NUOVO set |
|
set |
|
crea un NUOVO set |
|
set |
|
crea un NUOVO set |
|
set |
|
crea un NUOVO set |
|
|
|
Controlla se due insiemi sono uguali o differenti |
len
[17]:
len( {'a','b','c'} )
[17]:
3
[18]:
len( set() )
[18]:
0
Esercizio - distinte
Data una stringa parola
, scrivere del codice che
stampa le lettere distinte presenti in
parola
ordinate alfabeticamente (senza le quadre!), assieme al loro numerostampa il numero di lettere duplicate trovate in totale
Esempio 1 - data:
parola = "ababbbbcdd"
dopo il tuo codice deve stampare
parola : ababbbbcdd
4 distinte : a,b,c,d
6 duplicate
Esempio 2 - data:
parola = "cccccaaabbbb"
dopo il tuo codice deve stampare
parola : cccccaaabbbb
3 distinte : a,b,c
9 duplicate
[19]:
# scrivi qui
parola : ababbbbcdd
4 distinte : a,b,c,d
6 duplicate
Appartenenza
Come per tutte le sequenze, se vogliamo verificare se un elemento immutabile è contenuto in un insieme possiamo usare l’operatore in
che ci ritorna un valore booleano:
[20]:
'a' in {'m','e','n','t','a'}
[20]:
True
[21]:
'z' in {'m','e','n','t','a'}
[21]:
False
in
NEGLI INSIEMI E’ UN’OPERAZIONE MOLTO VELOCE
La velocità dell’operatore in
NON dipende dalla dimensione dell’insieme
Questo è una differenza sostanziale rispetto alle altre sequenze già viste: se provi a cercare un elemento con in
su stringhe, liste o tuple, Python potrebbe dover scorrere tutta la lista se per sfortuna l’elemento da cercare è alla fine (o non c’è proprio).
Cosa possiamo cercare?
Il prezzo da pagare per avere una ricerca veloce è che possiamo cercare solo elementi immutabili. Prima di effettuare la ricerca Python prova a ricavare un etichetta hash dall’oggetto cercato: se ci riesce procede con la ricerca, altrimenti si offende lanciando un’eccezione. Per esempio, se proviamo a cercare un elemento mutabile come una lista, Python si rifiuterà:
["lattuga", "rucola"] in { ("cavoli", "verze"), ("lattuga", "rucola"), ("rapanelli", "zucchine") }
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
/tmp/ipykernel_22984/2823749418.py in <module>
----> 1 ["lattuga", "rucola"] in { ("cavoli", "verze"), ("lattuga", "rucola"), ("rapanelli", "zucchine") }
TypeError: unhashable type: 'list'
DOMANDA: Che risultato produce questo codice?
("rucola", "rapanelli") in { ("cavoli", "verze"), ("lattuga", "rucola"), ("rapanelli", "zucchine") }
DOMANDA: Guarda le seguenti espressioni, e per ciascuna cerca di indovinare quale risultato producono (o se danno errore):
2*10 in {10,20,30,40}
'four' in {'f','o','u','r'}
'aa' in set('aa')
'a' in set(['a','a'])
[3 in {3,4}, 6 in {3,4} ]
4 in set([1,2,3]*4)
2 in {len('3.4'.split('.'))}
{'c','d'} in {('a','b'), ('c','d'), ('e','f')}
{'c','d'} in [{'a','b'}, {'d','c'}, {'e','f'}]
not in
Per verificare se qualcosa non appartiene ad una sequenza, possiamo usare due forme:
not in - forma 1:
[22]:
"carota" not in {"anguria","banana","mela"}
[22]:
True
[23]:
"anguria" not in {"anguria","banana","mela"}
[23]:
False
not in - forma 2
[24]:
not "carota" in {"anguria","banana","mela"}
[24]:
True
[25]:
not "anguria" in {"anguria","banana","mela"}
[25]:
False
DOMANDA: Guarda le seguenti espressioni, e per ciascuna cerca di indovinare quale risultato producono (o se danno errore):
4 not in {1,2,3}
'3' not in {1,2,3}
not 'a' in {'b','c'}
not {} in set([])
{not 'a' in {'a'}}
4 not in set((4,))
() not in set([()])
DOMANDA: le seguenti espressioni sono simili. Cosa hanno in comune? Qual’è la differenza con l’ultima (oltre al fatto che è su un insieme)?
'e' in 'abcde'
'abcde'.find('e') >= 0
'abcde'.count('e') > 0
'e' in ['a','b','c','d','e']
['a','b','c','d','e'].count('e') > 0
'e' in ('a','b','c','d','e')
('a','b','c','d','e').count('e') > 0
'e' in {'a','b','c','d','e'}
Unione
L’operatore di unione |
(detto pipe) produce un NUOVO insieme contenente tutti gli elementi del primo e del secondo insieme.
[26]:
{'a','b','c'} | {'b','c','d','e'}
[26]:
{'a', 'b', 'c', 'd', 'e'}
Notiamo che non ci sono elementi duplicati
ESERCIZIO: E se usiamo il +
? Prova a scrivere in una cella {'a','b'} + {'c','d','e'}
. Cosa succede?
[27]:
# scrivi qui
DOMANDA: Guarda le seguenti espressioni, e per ciascuna cerca di indovinare quale risultato producono (o se danno errore):
{'a','d','b'}|{'a','b','c'}
{'a'}|{'a'}
{'a'|'b'}
{1|2|3}
{'a'|'b'|'a'}
{{'a'}|{'b'}|{'a'}}
[1,2,3] | [3,4]
(1,2,3) | (3,4)
"abc" | "cd"
{'a'} | set(['a','b'])
set(".".join('pacca'))
'{a}'|'{b}'|'{a}'
set((1,2,3))|set([len([4,5])])
{()}|{()}
{'|'}|{'|'}
DOMANDA: Dati insiemi x
e y
qualunque, questa espressione
len(x | y) <= len(x) + len(y)
produce:
un errore (quale?)
sempre
True
sempre
False
a volte
True
a volteFalse
a seconda dei valori dix
ey
Esercizio: tuttotranne 1
Scrivi del codice che crea un set s4
che contiene tutti gli elementi di s1
ed s2
ma non contiene gli elementi di s3
.
Il tuo codice dovrebbe funzionare con qualunque insieme
s1
,s2
,s3
Esempio - dati
s1 = set(['a','b','c','d','e'])
s2 = set(['b','c','f','g'])
s3 = set(['b','f'])
Dopo il tuo codice dovresti ottenere
>>> print(s4)
{'c', 'a', 'd', 'e', 'g'}
[28]:
s1 = set(['a','b','c','d','e'])
s2 = set(['b','c','f','g'])
s3 = set(['b','f'])
# scrivi qui
Intersezione
L’operatore di intersezione &
produce un NUOVO insieme contenente tutti gli elementi in comune del primo e secondo insieme
[29]:
{'a','b','c'} & {'b','c','d','e'}
[29]:
{'b', 'c'}
DOMANDA: Guarda le seguenti espressioni, e per ciascuna cerca di indovinare quale risultato producono (o se danno errore):
{0} & {0,1}
{0,1} & {0}
set("capra") & set("campa")
set("cba") & set("dcb")
{len([1,2,3]),4} & {len([5,6,7])}
{1,2} & {1,2}
{0,1} & {}
{0,1} & set()
'cc' in (set('pacca') & set('zucca'))
set([1,2,3,4,5][::2]) & set([1,2,3,4,5][2::2])
{((),)} & {()}
{(())} & {()}
Differenza
L’operatore di differenza -
produce un NUOVO insieme contenente tutti gli elementi del primo insieme eccetto queli del secondo:
[30]:
{'a','b','c','d'} - {'b','c','e','f','g'}
[30]:
{'a', 'd'}
DOMANDA: Guarda le seguenti espressioni, e per ciascuna cerca di indovinare quale risultato producono (o se danno errore):
{3,4,2}-2
{1,2,3}-{3,4}
'{"a"}-{"a"}'
{1,2,3}--{3,4}
{1,2,3}-(-{3,4})
set("chiodo") - set("chiave")
set("prova") - set("prova".capitalize())
set("BarbA") - set("BARBA".lower())
'c' in (set('parco') - set('cassa'))
set([(1,2),(3,4),(5,6)]) - set([(2,3),(4,5)])
set([(1,2),(3,4),(5,6)]) - set([(3,4),(5,6)])
{1,2,3} - set()
set() - {1,2,3}
DOMANDA: Dati due insiemi qualunque x
e y
, il seguente codice cosa produce? Un errore? E’ semplificabile?
(x & y) | (x-y)
Differenza simmetrica
La differenza simmetrica di due insiemi è la loro unione meno la loro intersezione, cioè tutti gli elementi tranne quelli in comune
In Python si può esprimere direttamente con l’operatore ^
:
[31]:
{'a','b','c'} ^ {'b','c','d','e'}
[31]:
{'a', 'd', 'e'}
Verifichiamo che il risultato corrisponda alla definizione:
[32]:
s1 = {'a','b','c'}
s2 = {'b','c','d','e'}
(s1 | s2) - (s1 & s2)
[32]:
{'a', 'd', 'e'}
DOMANDA: Guarda le seguenti espressioni, e per ciascuna cerca di indovinare quale risultato producono (o se danno errore):
{'p','e','p','p','o'} ^ {'p','a','p','p','e'}
{'ab','cd'} ^ {'ba','dc'}
set('brodino') ^ set('bordo')
set((1,2,5,3,2,3,1)) ^ set((1,4,3,2))
DOMANDA: Dati 3 insiemi A
, B
, C
, qual’è l’espressione per ottenere la parte in azzurro?
DOMANDA: Se usiamo i seguenti valori nell’esercizio precedente, l’insieme che indica la parte in blu cosa conterrebbe?
A = {'a','ab','ac','abc'}
B = {'b','ab','bc','abc'}
C = {'c','ac','bc','abc'}
Una volta fatta la supposizione, prova ad eseguire la formula che hai trovato nell’esercizio precedente con i valori forniti e confronta i risultati con la soluzione.
Mostra rispostaUguaglianza
Possiamo verificare se due insiemi sono uguali con l’operatore di uguaglianza ==
, che dati due insiemi ritorna True
se contengono elementi uguali oppure False
altrimenti:
[33]:
{4,3,6} == {4,3,6}
[33]:
True
[34]:
{4,3,6} == {4,3}
[34]:
False
[35]:
{4,3,6} == {4,3,6, 'ciao'}
[35]:
False
Attento alla rimozione dei duplicati !
[36]:
{2,8} == {2,2,8}
[36]:
True
Per verificare la disuguaglianza, possiamo usare l’operatore !=
:
[37]:
{2,5} != {2,5}
[37]:
False
[38]:
{4,6,0} != {2,8}
[38]:
True
[39]:
{4,6,0} != {4,6,0,2}
[39]:
True
Attenti ai duplicati e all’ordine!
[40]:
{0,1} != {1,0,0,0,0,0,0,0}
[40]:
False
DOMANDA: Guarda le seguenti espressioni, e per ciascuna cerca di indovinare quale risultato producono (o se danno errore):
{2 == 2, 3 == 3}
{1,2,3,2,1} == {1,1,2,2,3,3}
{'aa'} == {'a'}
set('aa') == {'a'}
[{1,2,3}] == {[1,2,3]}
set({1,2,3}) == {1,2,3}
set((1,2,3)) == {(1,2,3)}
{'aa'} != {'a', 'aa'}
{set() != set()}
set('scarpa') == set('capras')
set('papa') != set('pappa')
set('pappa') != set('reale')
{(),()} == {(())}
{(),()} != {(()), (())}
[set()] == [set(),set()]
(set('gosh') | set('posh')) == (set('shopping') - set('in'))
Metodi simili agli operatori
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 |
---|---|---|---|
|
|
unione, crea un NUOVO set |
| |
|
|
intersezione, crea un NUOVO set |
|
|
|
differenza, crea un NUOVO set |
|
|
|
differenza simmetrica, crea un NUOVO set |
|
Metodi che MODIFICANO il primo insieme su cui sono chiamati (e ritornano None
!):
Metodo |
Risultato |
Descrizione |
---|---|---|
|
|
unione, MODIFICA |
|
|
intersezione, MODIFICA |
|
|
differenza, MODIFICA |
|
|
differenza simmetrica, MODIFICA |
union
Guarderemo solo union
/update
, gli altri si comportano in modo analoghi
Con union
dato un insieme e una generica sequenza (quindi non necessariamente un insieme) possiamo creare un NUOVO insieme:
[41]:
sa = {'g','a','r','a'}
[42]:
la = ['a','g','r','a','r','i','o']
[43]:
sb = sa.union(la)
[44]:
sb
[44]:
{'a', 'g', 'i', 'o', 'r'}
ESERCIZIO: con union
possiamo usare sequenze arbitrarie, invece con gli operatori no. Prova a scrivere {1,2,3} | [2,3,4]
e guarda cosa succede.
[45]:
# scrivi qui
Possiamo verificare che union
crei un nuovo insieme con Python Tutor:
[46]:
sa = {'g','a','r','a'}
la = ['a','g','r','a','r','i','o']
sb = sa.union(la)
jupman.pytut()
[46]:
update
Se vogliamo invece MODIFICARE il primo insieme, possiamo utilizzare i metodi che terminano con la parola update
:
[47]:
sa = {'g','a','r','a'}
[48]:
la = ['a','g','r','a','r','i','o']
[49]:
sa.update(la)
[50]:
print(sa)
{'a', 'o', 'i', 'g', 'r'}
DOMANDA: che cosa ha ritornato la chiamata ad update
?
Guardiamo che è successo con Python Tutor - per evidenziare cosa è stato ritornato da update aggiungiamo anche un x =
:
[51]:
sa = {'g','a','r','a'}
la = ['a','g','r','a','r','i','o']
x = sa.update(la)
print(sa)
print(x)
jupman.pytut()
{'a', 'o', 'i', 'g', 'r'}
None
[51]:
DOMANDA: Guarda i seguenti pezzi di codice, e per ciascuno cerca di indovinare quale risultato producono (o se danno errore):
set('case').intersection('sebo') == 'se'
set('naso').difference('caso')
s = {1,2,3} s.intersection_update([2,3,4]) print(s)
s = {1,2,3} s = s & [2,3,4]
s = set('cartone') s = s.intersection('parto') print(s)
sa = set("mastice") sb = sa.difference("mastro").difference("collo") print(sa) print(sb)
sa = set("mastice") sb = sa.difference_update("mastro").difference_update("collo") print(sa) print(sb)
Esercizio - tuttotranne 2
Dati i set s1
, s2
e s3
, scrivere del codice che MODIFICA s1
in modo che contenga anche gli elementi di s2
ma non contenga gli elementi di s3
.
Il tuo codice dovrebbe funzionare con qualunque insieme
s1
,s2
,s3
NON creare nuovi set
Esempio - dati
s1 = set(['a','b','c','d','e'])
s2 = set(['b','c','f','g'])
s3 = set(['b','f'])
Dopo il tuo codice dovresti ottenere
>>> print(s1)
{'a', 'g', 'e', 'd', 'c'}
[52]:
s1 = set(['a','b','c','d','e'])
s2 = set(['b','c','f','g'])
s3 = set(['b','f'])
# scrivi qui
Altri metodi
Metodo |
Risultato |
Descrizione |
---|---|---|
|
aggiunge l’elemento specificato - se già presente non fa nulla) |
|
|
rimuove l’elemento specificato - se non presente solleva errore |
|
|
rimuove l’elemento specificato - se non presente non fa nulla |
|
|
|
rimuove un elemento arbitrario dall’insieme e lo ritorna |
|
|
rimuove tutti gli elementi |
|
verifica se |
|
|
verifica se |
|
|
verifica se |
add
Dato un insieme, possiamo aggiungergli un elemento con il metodo .add
:
[53]:
s = {3,7,4}
[54]:
s.add(5)
[55]:
s
[55]:
{3, 4, 5, 7}
Se aggiungiamo lo stesso elemento due volte, non accade nulla:
[56]:
s.add(5)
[57]:
s
[57]:
{3, 4, 5, 7}
DOMANDA: Se scriviamo questo codice, che risultato otteniamo?
s = {'a','b'}
s.add({'c','d','e'})
print(s)
stampa
{'a','b','c','d','e'}
stampa
{{'a','b','c','d','e'}}
stampa
{'a','b',{'c','d','e'}}
un errore (quale?)
DOMANDA: Guarda il codice seguente, che risultato produce?
x = {'a','b'}
y = set(x)
x.add('c')
print('x=',x)
print('y=',y)
un errore (quale?)
x
ey
saranno uguali (come?)x
ey
saranno diversi (come?)
[58]:
x = {'a','b'}
y = set(x)
x.add('c')
jupman.pytut()
[58]:
remove
Il metodo remove
toglie un elemento specificato dall’insieme. Se non esiste, produce un errore:
[59]:
s = {'a','b','c'}
[60]:
s.remove('b')
[61]:
s
[61]:
{'a', 'c'}
[62]:
s.remove('c')
[63]:
s
[63]:
{'a'}
s.remove('z')
---------------------------------------------------------------------------
KeyError Traceback (most recent call last)
<ipython-input-266-a9e7a977e50c> in <module>
----> 1 s.remove('z')
KeyError: 'z'
Esercizio - bababiba
Data una stringa scritta
di esattamente 4 sillabe da due caratteri ciascuna, creare un insieme s
che contenga delle tuple con 2 caratteri ciascuna. Ogni tupla deve rappresentare una sillaba presa da scritta
.
per aggiungere elementi all’insieme, usa solo
add
il tuo codice deve funzionare con qualunque
scritta
da 4 bisillabe
Esempio 1 - data:
scritta = "bababiba"
dopo il tuo codice, deve risultare:
>>> print(s)
{('b', 'a'), ('b', 'i')}
Esempio 2 - data:
scritta = "rubareru"
dopo il tuo codice, deve risultare:
>>> print(s)
{('r', 'u'), ('b', 'a'), ('r', 'e')}
[64]:
scritta = "bababiba"
#scritta = "rubareru"
# scrivi qui
discard
Il metodo discard
toglie un elemento specificato dall’insieme. Se non esiste, non fa nulla:
[65]:
s = {'a','b','c'}
[66]:
s.discard('a')
[67]:
s
[67]:
{'b', 'c'}
[68]:
s.discard('c')
[69]:
s
[69]:
{'b'}
[70]:
s.discard('z')
[71]:
s
[71]:
{'b'}
Esercizio - spazzatura
✪✪ Un impianto di processamento rifiuti riceve un carico di spazzatura
, che rappresentiamo come insieme di stringhe:
spazzatura = {'alcheni','verdura','mercurio','carta'}
Per rimuovere gli elementi contaminanti che potrebbero essere presenti (NOTA: non sempre sono presenti !), l’impianto ha esattamente 3 filtri
(come lista di stringhe) che applicherà in serie alla spazzatura:
filtri = ['cadmio','mercurio','alcheni']
Per ogni filtro applicato, si vuole vedere lo stato della spazzatura
processata, per vedere se il filtro ha effettivamente rimosso il contaminante (se presente)
Alla fine, si vuole anche stampare tutti e soli i contaminanti che sono stati effettivamente rimossi (mettili come insieme nella variabile separati
)
NON usare comandi
if
NON serve usare cicli (il numero di filtri è fisso a 3, puoi usare copia e incolla di codice)
Il tuo codice deve funzionare per qualsiasi lista
filtri
di 3 elementi e qualsiasi insiemespazzatura
Esempio - dati:
filtri = ['cadmio','mercurio','alcheni']
spazzatura = {'alcheni','verdura','mercurio','carta'}
Dopo il tuo codice, deve mostrare:
spazzatura iniziale: {'verdura', 'carta', 'alcheni', 'mercurio'}
Applico filtro per cadmio : {'verdura', 'carta', 'alcheni', 'mercurio'}
Applico filtro per mercurio : {'verdura', 'carta', 'alcheni'}
Applico filtro per alcheni : {'verdura', 'carta'}
Contaminanti separati: {'alcheni', 'mercurio'}
[72]:
filtri = ['cadmio','mercurio','alcheni']
spazzatura = {'alcheni','verdura','mercurio','carta'}
separati = spazzatura.intersection(filtri) # crea un NUOVO insieme
# scrivi qui
issubset
Per verificare se tutti gli elementi di un insieme sa
sono contenuti in un altro insieme sb
possiamo scrivere sa.issubset(sb)
. Esempi:
[73]:
{2,4}.issubset({1,2,3,4})
[73]:
True
[74]:
{3,5}.issubset({1,2,3,4})
[74]:
False
ATTENZIONE: l’insieme vuoto è sempre considerato un sottoinsieme di un qualsiasi insieme
[75]:
set().issubset({3,4,2,5})
[75]:
True
issuperset
Per verificare se un insieme sa
contiene tutti gli elementi di un altro insieme sb
possiamo scrivere sa.issuperset(sb)
. Esempi:
[76]:
{1,2,3,4,5}.issuperset({1,3,5})
[76]:
True
[77]:
{1,2,3,4,5}.issuperset({2,4})
[77]:
True
[78]:
{1,2,3,4,5}.issuperset({1,3,5,7,9})
[78]:
False
ATTENZIONE: l’insieme vuoto è sempre considerato un sottoinsieme di un qualsiasi insieme
[79]:
{1,2,3,4,5}.issuperset({})
[79]:
True
isdisjoint
Un insieme è disgiunto da un altro se non ha alcun elemento in comune, per verificarlo possiamo usare il metodo isdisjoint
:
[80]:
{1,3,5}.isdisjoint({2,4})
[80]:
True
[81]:
{1,3,5}.isdisjoint({2,3,4})
[81]:
False
DOMANDA: Dato un insieme qualsiasi x
, cosa produce la seguente espressione?
x.isdisjoint(x)
un errore (quale?)
sempre
True
sempre
False
True
oFalse
a seconda del valore dix
Esercizio - matrioska
✪✪ Data una lista insiemi
di esattamente 4 insiemi, la definiamo a matrioska se ogni insieme contiene tutti gli elementi del precedente insieme (più eventualmente altri). Scrivi del codice che STAMPA True
se la sequenza è a matrioska, altrimenti STAMPA False
.
NON usare
if
il tuo codice deve funzionare per qualunque sequenza di esattamente 4 insiemi
SUGGERIMENTO: puoi creare una lista di 3 booleani che verificano se un set è contenuto nel successivo…
Esempio 1 - data :
insiemi = [{'a','b'},
{'a','b','c'},
{'a','b','c','d','e'},
{'a','b','c','d','e','f','g','h','i'}]
dopo il tuo codice, deve stampare:
La sequenza è a matrioska? True
Esempio 2 - data :
insiemi = [{'a','b'},
{'a','b','c'},
{'a','e','d'},
{'a','b','d','e'}]
dopo il tuo codice, deve stampare:
La sequenza è a matrioska? False
[82]:
insiemi = [{'a','b'},
{'a','b','c'},
{'a','b','c','d','e'},
{'a','b','c','d','e','f','g','h','i'}]
#insiemi = [{'a','b'},
# {'a','b','c'},
# {'a','e','d'},
# {'a','b','d','e'}]
# scrivi qui
Prosegui
Prosegui con le challenges