Insiemi e dizionari

Introduzione

I dizionari (dict) sono delle strutture dati in cui gli elementi sono memorizzati in coppie chiave/valore. Sono simili a quelli che in altri linguaggi di programmazione vengono chiamati hash o array associativi.

Negli insiemi (set), invece, sono presenti solo le chiavi.

Valori ammissibili come chiavi

Come chiave di un insieme o di un dizionario, possiamo usare qualsiasi valore di tipo immutabile (oggetti di tipo int, str, frozenset, tuple). Teoricamente anche i valori di tipo float potrebbero essere usati, ma questo è sconsigliato. Non possono invece essere usati come chiavi i valori di oggetti mutabili (liste, dizionari, insiemi) perché il valore della funzione hash per questi oggetti cambia con il cambiare del valore.

Gli insiemi

Un insieme (set) può essere creato usando la notazione delle parentesi graffe, specificando solo le chiavi:

>>> days={'monday', 'tuesday', 'wednesday', 'thursday', 'friday'}
>>> print(days)
{'monday', 'tuesday', 'friday', 'wednesday', 'thursday'}

È importante notare che gli insiemi non ammettono chiavi duplicate (non viene segnalato un errore, semplicemente il valore duplicato viene ignorato), e che non è garantito l'ordine (nella visualizzazione l'ordine può essere diverso rispetto a quello in cui sono stati inseriti i dati).

>>> n=(12,12,32,33)  # n è una lista
>>> m=set(n)  # creo m come insieme, a partire dai valori di n
>>> print(m)  # visualizzo m, e vedo che il doppio 12 non c'è
{32, 33, 12}

Per rimuovere un elemento da un insieme, si usa il metodo remove():

>>> m.remove(12)
>>> m
{32, 33}

Per aggiungere un elemento a un insieme, si usa il metodo add():

>>> m.add(15)
>>> m
{32, 33, 15}

Gli insiemi immutabili: frozenset

Esiste una variante di insieme di tipo immutabile, nel quale gli elementi non possono essere aggiunti, rimossi o modificati. Si chiama frozenset.

>>> n=(11,21,31,41) # n è una lista
>>> m=frozenset(n)  # creo m come insieme congelato, a partire dai valori di n
>>> m.add(51)

Traceback (most recent call last):
  File "/tmp/frozenset.py", line 3, in <module>
    m.add(51)
AttributeError: 'frozenset' object has no attribute 'add'

I dizionari

Per creare (e/o aggiungere elementi a) un dizionario si possono usare diverse sintassi. Presentiamo qui di seguito alcuni esempi, corredati da alcuni esempi di visualizzazione delle coppie:

months={ 'jan': 'Gennaio', 'feb': 'Febbraio', 'mar': 'Marzo' }

# equivalente a:
# months=dict(jan='Gennaio', feb='Febbraio', mar='Marzo')

print(months)
{'jan': 'Gennaio', 'mar': 'Marzo', 'feb': 'Febbraio'}

months['apr'] = 'Aprile'
months['may'] = 'Maggio'
months['june'] = 'Giugno'

print(months)
{'mar': 'Marzo', 'feb': 'Febbraio', 'apr': 'Aprile', 'june': 'Giugno', 'jan': 'Gennaio', 'may': 'Maggio'}

Il metodo keys() restituisce le chiavi (in forma di object view, vedi più avanti):

print('\nChiavi:')
for key in months.keys():
    print(key)

Chiavi:
mar
feb
apr
june
jan
may

Il metodo values() restituisce i valori (in forma di object view, vedi più avanti):

print('\nValori:')
for value in months.values():
    print(value)
Valori:
Marzo
Febbraio
Aprile
Giugno
Gennaio
Maggio

Il metodo items() restituisce l'insieme delle tuple chiave/valore (in forma di object view, vedi più avanti)::

print('\nChiavi e valori:')
for key, value in months.items():
    print(key, ' --> ', value)

Chiavi e valori:
mar  -->  Marzo
feb  -->  Febbraio
apr  -->  Aprile
june  -->  Giugno
jan  -->  Gennaio
may  -->  Maggio

Se si desidera creare un dizionario a partire da due liste (o due tuple), delle quali una contiene le chiavi e l'altra i valori, è possibile usare la funzione zip:

weekdays=dict(zip(
    ('mon', 'tue', 'wed', 'thu', 'fri', 'sat', 'sun'),
    ('Lunedì', 'Martedì', 'Mercoledì', 'Giovedì', 'Venerdì', 'Sabato', 'Domenica')
    ))

print(weekdays)

{'wed': 'Mercoledì', 'sun': 'Domenica', 'fri': 'Venerdì', 'tue': 'Martedì', 'mon': 'Lunedì', 'thu': 'Giovedì', 'sat': 'Sabato'}

Per rimuovere un elemento da un dizionario, si usa la parola chiave del:

>>> d={'a':100, 'b':200, 'k':400}
>>> d
{'a': 100, 'k': 400, 'b': 200}
>>> del d['b']
>>> d
{'a': 100, 'k': 400}

Estrazione di valori

Per accedere in modo sicuro al valore di un dizionario basandosi su una chiave (che potrebbe non esistere) possiamo usare il suo metodo get(), che consente anche di definire un valore di default (usato nel caso di mancanza dell'elemento):

>>> k=dict(a=12, b=13, c=25)
>>> print(k)
{'a': 12, 'c': 25, 'b': 13}
>>> v=k.get('a')
>>> print(v)
12
>>> v=k.get('n')
>>> print(v)
None
>>> v=k.get('n', 'No value defined')
>>> print(v)
No value defined

Operazioni insiemistiche

Sui dizionari e sugli insiemi si possono fare operazioni di tipo insiemistico. La più comune è l'uso dell'operatore in:

for month in ('Maggio', 'Giugno', 'Luglio', 'Agosto'):
    if month in months.values():
        print('%s appartiene all\'insieme dei mesi' % month)
    else:
        print('%s NON appartiene all\'insieme dei mesi' % month)

Con i dati impostati precedentemente, l'output sarebbe il seguente:

Maggio appartiene all'insieme dei mesi
Giugno appartiene all'insieme dei mesi
Luglio NON appartiene all'insieme dei mesi
Agosto NON appartiene all'insieme dei mesi

Inoltre, sono supportate le operazioni di intersezione, unione, differenza e differenza simmetrica:

evens={2,4,6,8,10,12,14,16,18,20} # questo è un set
multiples_of_three={3,6,9,12,15,18}

print('Intersezione: ', evens & multiples_of_three)
print('Unione: ', evens | multiples_of_three)
print('Differenza simmetrica: ', evens ^ multiples_of_three)
print('Differenza1: ', evens - multiples_of_three)
print('Differenza2: ', multiples_of_three - evens)

Output:
Intersezione:  {18, 12, 6}
Unione:  {2, 3, 4, 6, 8, 9, 10, 12, 14, 15, 16, 18, 20}
Differenza simmetrica:  {2, 3, 4, 8, 9, 10, 14, 15, 16, 20}
Differenza1:  {2, 4, 8, 10, 14, 16, 20}
Differenza2:  {9, 3, 15}

Chiavi e valori come object view

Quando si estraggono le chiavi e i valori da un dizionario con i metodi keys(), values() e items(), si ottiene un riferimento dinamico al dizionario stesso. Ciò significa che se il dizionario cambia, le modifiche avranno un riflsso sulle chiavi e i valori ottenuti. Se vogliamo una copia statica, dobbiamo farcela esplicitamente, mettendo i valori estratti in una tupla. Chiariamo questo concetto con un esempio pratico:

months={ 'jan': 'Gennaio', 'feb': 'Febbraio', 'mar': 'Marzo' }

print(months)
{'jan': 'Gennaio', 'mar': 'Marzo', 'feb': 'Febbraio'}

keys=months.keys()  # creiamo un riferimento dinamico alle chiavi
keysCopy=tuple(months.keys())  # creiamo una copia delle chiavi esistenti ora

values=months.values() # come sopra, ma per i valori
valuesCopy=tuple(months.values()) # copia dei valori esistenti ora

del months['jan'] # eliminiamo l'elemento con chiave 'jan'
months['apr']='Aprile' # aggiungiamo un elemento con chiave 'apr'

print(keys) # otteniamo la lista aggiornata
dict_keys(['apr', 'mar', 'feb'])
print(keysCopy) # otteniamo la copia (non aggiornata)
('jan', 'mar', 'feb')

print(values) # come sopra
dict_values(['Aprile', 'Marzo', 'Febbraio'])
print(valuesCopy) # come sopra
('Gennaio', 'Marzo', 'Febbraio')

results matching ""

    No results matching ""