W3docs

Dizionari Python

Impara i dizionari Python: crea, accedi, aggiorna, elimina, itera e usa le comprehension con esempi chiari e gli errori più comuni.

Un dizionario Python è una collezione mutabile e ordinata di coppie chiave-valore. A differenza delle liste o delle tuple (che usano posizioni intere), un dizionario ti permette di etichettare ogni valore con una chiave significativa — rendendo le ricerche veloci e il codice più leggibile. I dizionari sono uno dei tipi built-in più utilizzati in Python e sono alla base della gestione di JSON, della configurazione, del conteggio delle parole e molto altro.

Questo capitolo copre tutto ciò che devi sapere per usare i dizionari con sicurezza: creazione, accesso, modifica, eliminazione, iterazione, comprehension e gli errori più comuni.

Capitoli correlati: Metodi dei Dizionari | Dizionari Annidati | Cicli sui Dizionari | Copiare i Dizionari | Comprehension Python

Cos'è un Dizionario?

Un dizionario associa chiavi uniche e hashable a valori di qualsiasi tipo. La regola fondamentale: le chiavi devono essere immutabili — string, numeri e tuple di immutabili sono tutti validi; liste e altri dizionari non lo sono.

# string keys → integer values
inventory = {'apple': 10, 'banana': 5, 'orange': 8}

# mixed value types are fine
person = {'name': 'Alice', 'age': 30, 'active': True}

# tuple keys work because tuples are immutable
grid = {(0, 0): 'origin', (1, 0): 'east', (0, 1): 'north'}

A partire da Python 3.7, i dizionari mantengono l'ordine di inserimento — iterare su un dizionario restituisce sempre le chiavi nell'ordine in cui sono state aggiunte.

Creare un Dizionario

Letterale con parentesi graffe

Il modo più comune: separare le coppie chiave-valore con virgole, usare i due punti tra ogni chiave e il suo valore, e racchiudere il tutto in {}.

config = {'host': 'localhost', 'port': 5432, 'debug': True}
print(config)
# {'host': 'localhost', 'port': 5432, 'debug': True}

Un dizionario vuoto è semplicemente {}.

empty = {}
print(type(empty))  # <class 'dict'>

Costruttore dict()

Passa argomenti keyword a dict() quando le tue chiavi sono identificatori Python validi:

config = dict(host='localhost', port=5432, debug=True)
print(config)
# {'host': 'localhost', 'port': 5432, 'debug': True}

Puoi anche passare un iterabile di sequenze a due elementi:

pairs = [('x', 10), ('y', 20)]
point = dict(pairs)
print(point)  # {'x': 10, 'y': 20}

dict.fromkeys()

Crea un dizionario da una lista di chiavi, tutte condividendo lo stesso valore iniziale:

defaults = dict.fromkeys(['timeout', 'retries', 'verbose'], 0)
print(defaults)
# {'timeout': 0, 'retries': 0, 'verbose': 0}

Attenzione: se il valore predefinito è un oggetto mutabile (come una lista), tutte le chiavi condivideranno lo stesso oggetto. Usa invece una dictionary comprehension (mostrata sotto).

Dictionary comprehension

Un modo conciso per costruire un dizionario da qualsiasi iterabile:

squares = {x: x ** 2 for x in range(1, 6)}
print(squares)
# {1: 1, 2: 4, 3: 9, 4: 16, 5: 25}

Vedi Comprehension Python per la sintassi completa.

Accedere ai Valori

Ricerca con parentesi quadre

inventory = {'apple': 10, 'banana': 5, 'orange': 8}
print(inventory['apple'])   # 10

Se la chiave non esiste, Python solleva un KeyError:

try:
    print(inventory['grape'])
except KeyError as e:
    print(f'KeyError: {e}')   # KeyError: 'grape'

get() — ricerca sicura con valore predefinito

dict.get(key, default) restituisce il valore se la chiave esiste, oppure default (che è None se omesso) altrimenti — senza sollevare eccezioni.

print(inventory.get('grape'))       # None
print(inventory.get('grape', 0))    # 0
print(inventory.get('apple', 0))    # 10

Usa .get() ogni volta che non sei sicuro che una chiave esista. Usa la ricerca con parentesi quadre quando la chiave deve essere presente — una chiave mancante è allora un vero bug che dovrebbe emergere come errore.

Verificare se una chiave esiste

print('apple' in inventory)    # True
print('grape' in inventory)    # False
print('grape' not in inventory) # True

in controlla le chiavi, non i valori. Viene eseguito in tempo O(1) medio — costante, indipendentemente dalla dimensione del dizionario.

Aggiungere e Aggiornare Elementi

Aggiungere una nuova coppia chiave-valore

Assegna a una chiave che non esiste ancora:

inventory['grape'] = 12
print(inventory)
# {'apple': 10, 'banana': 5, 'orange': 8, 'grape': 12}

Aggiornare un valore esistente

Assegna a una chiave che esiste già — il vecchio valore viene sostituito:

inventory['apple'] = 15
print(inventory['apple'])  # 15

update() — aggiunta o sovrascrittura in blocco

Passa un altro dizionario o un iterabile di coppie chiave-valore:

inventory.update({'banana': 7, 'mango': 3})
print(inventory)
# {'apple': 15, 'banana': 7, 'orange': 8, 'grape': 12, 'mango': 3}

Unione con | (Python 3.9+)

L'operatore | crea un nuovo dizionario unito. Se una chiave appare in entrambi, vince il lato destro:

a = {'x': 1, 'y': 2}
b = {'y': 99, 'z': 3}
merged = a | b
print(merged)   # {'x': 1, 'y': 99, 'z': 3}

Usa |= per unire b in a sul posto — equivalente a a.update(b) ma più leggibile.

setdefault() — inserisci solo se assente

dict.setdefault(key, default) inserisce la chiave con il valore predefinito se è assente, poi restituisce sempre il valore per quella chiave. Questo è più efficiente del pattern if key not in d: d[key] = default.

scores = {'Alice': 95}
scores.setdefault('Bob', 0)     # Bob absent → inserts 0, returns 0
scores.setdefault('Alice', 0)   # Alice present → does nothing, returns 95
print(scores)   # {'Alice': 95, 'Bob': 0}

Un caso d'uso classico è raggruppare elementi:

words = ['cat', 'car', 'bus', 'can', 'bat']
groups = {}
for word in words:
    groups.setdefault(word[0], []).append(word)
print(groups)
# {'c': ['cat', 'car', 'can'], 'b': ['bus', 'bat']}

Rimuovere Elementi

del — rimuovi per chiave

inventory = {'apple': 15, 'banana': 7, 'orange': 8, 'grape': 12}
del inventory['orange']
print(inventory)
# {'apple': 15, 'banana': 7, 'grape': 12}

del solleva KeyError se la chiave è assente. Per evitarlo, controlla prima con in, oppure usa pop() con un valore predefinito.

pop() — rimuovi e restituisci il valore

removed = inventory.pop('grape')
print(removed)      # 12
print(inventory)    # {'apple': 15, 'banana': 7}

Fornisci un secondo argomento per evitare KeyError quando la chiave potrebbe essere assente:

val = inventory.pop('pear', 'not found')
print(val)   # not found

popitem() — rimuovi l'ultimo elemento inserito (Python 3.7+)

d = {'a': 1, 'b': 2, 'c': 3}
last = d.popitem()
print(last)   # ('c', 3)
print(d)      # {'a': 1, 'b': 2}

clear() — rimuovi tutto

d = {'a': 1, 'b': 2}
d.clear()
print(d)   # {}

Iterare su un Dizionario

Tre viste consentono di iterare su diverse parti di un dizionario. Tutte e tre sono viste live — riflettono le modifiche al dizionario senza dover essere ricreate.

Chiavi (iterazione predefinita)

Iterare direttamente su un dizionario restituisce le sue chiavi:

person = {'name': 'Alice', 'age': 30, 'city': 'Paris'}

for key in person:
    print(key)
# name
# age
# city

person.keys() restituisce le stesse chiavi come oggetto vista dict_keys esplicito.

Valori

for val in person.values():
    print(val)
# Alice
# 30
# Paris

Coppie chiave-valore

for key, val in person.items():
    print(f'{key}: {val}')
# name: Alice
# age: 30
# city: Paris

.items() è la scelta più comune quando hai bisogno sia della chiave che del valore all'interno del ciclo. Vedi Cicli sui Dizionari per pattern avanzati.

Le viste sono live

d = {'a': 1}
keys_view = d.keys()
d['b'] = 2
print(keys_view)   # dict_keys(['a', 'b'])  ← reflects the new key

Dictionary Comprehension

Le dictionary comprehension permettono di costruire o trasformare dizionari in un'unica espressione leggibile.

Filtrare per valore

inventory = {'apple': 15, 'banana': 7, 'orange': 8, 'grape': 12, 'mango': 3}
popular = {k: v for k, v in inventory.items() if v >= 8}
print(popular)
# {'apple': 15, 'orange': 8, 'grape': 12}

Invertire un dizionario (scambiare chiavi e valori)

original = {'a': 1, 'b': 2, 'c': 3}
swapped = {v: k for k, v in original.items()}
print(swapped)   # {1: 'a', 2: 'b', 3: 'c'}

Questo funziona in modo sicuro solo quando tutti i valori sono unici.

Contatore di frequenza delle parole

sentence = 'the quick brown fox jumps over the lazy dog'
freq = {}
for word in sentence.split():
    freq[word] = freq.get(word, 0) + 1
print(freq)
# {'the': 2, 'quick': 1, 'brown': 1, 'fox': 1, ...}

Funzioni Built-in Utili

OperazioneEsempioRisultato
Lunghezzalen(inventory)numero di coppie chiave-valore
Copia (superficiale)inventory.copy()nuovo dict, stesse riferimenti
Converti in lista di chiavilist(inventory)['apple', 'banana', ...]
Chiavi ordinatesorted(inventory)['apple', 'banana', ...] in ordine alfabetico
Tutti i valori veri?all(inventory.values())True / False
Almeno un valore vero?any(inventory.values())True / False

Per un riferimento completo di tutti i metodi dei dizionari (copy, fromkeys, update, setdefault, popitem e altri), vedi Metodi dei Dizionari Python.

Errori Comuni

1. KeyError su chiave mancante — usa sempre .get() o in quando una chiave potrebbe non esistere.

2. Tipi di chiave non hashable — le liste non possono essere chiavi di dizionario perché sono mutabili. Usa una tupla al posto:

# This raises TypeError: unhashable type: 'list'
# bad = {[1, 2]: 'value'}

# Use a tuple:
coords = {(1, 2): 'A', (3, 4): 'B'}
print(coords[(1, 2)])  # A

3. Modifica durante l'iterazione — aggiungere o rimuovere chiavi mentre si itera su un dizionario solleva RuntimeError. Fai prima uno snapshot:

d = {'a': 1, 'b': 2, 'c': 3}
for key in list(d):          # list() copies the keys
    if d[key] < 2:
        del d[key]
print(d)   # {'b': 2, 'c': 3}

4. Copia superficiale vs. copia profondadict.copy() e {**d} effettuano entrambi una copia superficiale. I valori mutabili annidati (liste, dizionari) sono ancora condivisi. Usa copy.deepcopy() quando hai bisogno di copie completamente indipendenti. Vedi Copiare i Dizionari.

Dizionari vs. Altri Tipi di Collezione

Caratteristicadictlisttupleset
OrdinatoSì (3.7+)No
MutabileNo
Indicizzato perChiaveInteroIntero
DuplicatiChiavi: no; Valori: sìNo
Utilizzo principaleMappatura chiave-valoreSequenza ordinataSequenza immutabileUnicità / operazioni sugli insiemi

Quando hai bisogno di cercare qualcosa tramite un'etichetta significativa anziché una posizione, un dizionario è quasi sempre la scelta giusta. Per valori unici ordinati, considera un set. Per una semplice sequenza ordinata, usa una list.

Esercizio

Pratica
What is true about Python dictionaries according to the information given in the article?
What is true about Python dictionaries according to the information given in the article?
Was this page helpful?