Dizionari

Come collegare valori agli oggetti immutabili.

Python mette a disposizione del programmatore un’altra potente struttura di dati: i dizionari. Assomigliano alle liste, ma gli indici, invece di essere numeri successivi sono oggetti immutabili qualunque, possono essere numeri, stringhe o tuple. Esempio:

>>> d={}                 # 1
>>> d[1]="pippo"         # 2
>>> d["gigi"]="pluto"    # 3
>>> d[(2,6)]="paperino"  # 4
>>> print d
{1: 'pippo', (2, 6): 'paperino', 'gigi': 'pluto'}

Alcune osservazioni:

  1. d viene associato a un dizionario vuoto.
  2. al numero 1 viene associato il valore “pippo”
  3. alla stringa “gigi” viene associato il valore “pluto”
  4. alla tupla (2, 6) viene associato il valore “paperino”
  5. I dizionari mantengono le associazioni chiave-valore, non l’ordine degli elementi.

È possibile ottenere il valore associato ad una certa chiave o modificarlo usando la sintassi dell’indicizzazione:

>>> print d["gigi"]
pluto
>>> d["gigi"]="clarabella"
>>> print d["gigi"]
clarabella

Si può ottenere la lista di tutte le chiavi di un dizionario con il metodo <dict>.keys():

>>> print d.keys()
[1, (2, 6), 'gigi']

Se cerchiamo di ottenere il valore collegato ad una chiave non esistente nel dizionario si ottiene un errore:

>>> print d["mario"]

[...]KeyError: 'mario'

La classe dict mette a disposizione due metodi che permettono di trattare il caso di chiavi non presenti nel dizionario. Il metodo <dict>.get(<chiave>[, <valore>]) restituisce il valore collegato alla chiave se questa esiste, altrimenti restituisce il valore di default, non modifica il dizionario:

>>> print d.get("gigi", "clarabella")
pluto
>>> print d.get("mario", "clarabella")
clarabella
>>> d
{1: 'pippo', (2, 6): 'paperino', 'gigi': 'pluto'}

Il metodo <dict>.setdefault(<chiave>[, <valore>]) restituisce il valore collegato ad una certa chiave, ma, se non esiste, crea un elemento con quella chiave e il valore passato come secondo argomento:

>>> print d.setdefault(1, "clarabella")
pippo
>>> d
{1: 'pippo', (2, 6): 'paperino', 'gigi': 'pluto'}
>>> print d.setdefault(2, "clarabella")
clarabella
>>> d
{1: 'pippo', 2: 'clarabella', (2, 6): 'paperino', 'gigi': 'pluto'}

Se vogliamo contare tutte le parole presenti in un certo testo (io ho scaricato da Internet bibbia.txt), possiamo:

  1. predisporre un dizionario vuoto,
  2. per ogni linea del testo:
    1. spezzare la linea in una lista di parole e per ogni parola:
    2. aumentare di 1 il contatore di quella parola (partendo dal valore 0 se non esiste).
  3. estrarre tutte le chiavi e metterle in ordine, così è più comodo ricercare una parola,
  4. stampare le coppie parola, numero di occorrenze.

L’algoritmo si traduce facilmente in Python:

def contaparole(nomefile):
    contatore = {}
    for linea in file(nomefile):
        for parola in linea.split():
            contatore[parola]=1+contatore.get(parola, 0)
    parole = contatore.keys()
    parole.sort()
    for parola in parole:
        print "%25s: %s" % (parola, contatore[parola])

Per contare le occorrenze delle parole della bibbia impiega una frazione di secondo, poi impiega qualche minuto per stamparle tutte.

Riassumendo

  • Un dizionario vuoto è rappresentato da una coppia di parentesi graffe.

  • Un dizionario è una contenitore che associa oggetti (valori) a oggetti immutabili (chiavi).

  • Nei dizionari non è mantenuto l’ordine degli elementi, ma solo l’associazione chiave-valore.

  • È possibile ottenere la lista delle chiavi di un dizionario con il metodo <dict>keys().

  • Si può accedere ad un valore usando l’indice del dizionario: <dict>.[<chiave>].

  • Si può creare un elemento assegnando un valore a una chiave: <dict>.[<chiave>]=<valore>.

  • I due metodi:

    <dict>.get(<chiave>[,<valore>]),
    <dict>.setdefault(<chiave>[,<valore>]),
    

    permettono di trattare in modo uniforme i casi in cui non sappiamo se esiste un elemento con una certa chiave.

Prova tu

  1. Modifica contaparole() in modo che stampi gli elementi dal più frequente al più raro.
  2. Inserisci un “filtro” in modo che la punteggiatura e le maiuscole non abbiano influenza nei conteggi.