ProgrammazioneSviluppatore Python

Che cos'è un dizionario (dict) in Python, come è strutturato sotto il cofano e in quali casi il tipo dict può comportarsi in modo non standard?

Supera i colloqui con l'assistente IA Hintsage

Risposta.

Storia della questione:

I dizionari (dict) sono uno dei tipi di dati fondamentali in Python, rappresentando una struttura "chiave-valore". I dizionari sono stati introdotti sin dal primo Python, ma la loro implementazione interna e le caratteristiche di comportamento sono state costantemente perfezionate (ad esempio, in Python 3.7 è garantito l'ordine di inserimento).

Problema:

Comprendere come è costruito un dizionario è necessario per scrivere codice in modo efficace. Senza conoscere le sottigliezze, possono sorgere bug quando si utilizzano tipi mutabili come chiavi, durante la copia di dizionari annidati, e in operazioni non standard.

Soluzione:

Il dizionario è implementato come una tabella hash, le chiavi devono essere necessariamente hashabili (immutabili). L'accesso al valore tramite la chiave funziona vicino a O(1), ma in alcune condizioni ci possono essere particolarità — ad esempio, durante le collisioni o nel trattamento di grandi quantità di dati.

Esempio di codice:

person = {'name': 'Alice', 'age': 30} person['city'] = 'Moscow' print(person['name']) # Alice

Caratteristiche chiave:

  • Le chiavi devono essere immutabili e hashabili (ad esempio, str, int, tuple senza oggetti mutabili).
  • Il dict in Python 3.7 e versioni successive conserva l'ordine di inserimento degli elementi.
  • dict è ottimo per ricerche, aggregazioni, mappature.

Domande trabocchetto.

È possibile utilizzare una lista (list) come chiave in dict?

No, le liste sono mutabili e non sono hashabili. Tentare di utilizzare una lista genererà un errore.

d = {} d[[1, 2, 3]] = 'value' # TypeError: unhashable type: 'list'

Cosa succede se si usano due tuple con contenuti identici come chiave?

Se entrambe le tuple contengono dati identici e sono immutabili, vengono considerate uguali e le chiavi nel dizionario coincideranno:

t1 = (1, 2) t2 = (1, 2) d = {t1: 'a'} print(d[t2]) # 'a'

Cambia l'ordine di iterazione degli elementi del dizionario durante la copia?

Nelle versioni Python 3.7+ l'ordine sarà mantenuto. Nelle versioni precedenti, l'ordine di iterazione non è garantito.

d1 = {'a': 1, 'b': 2} d2 = dict(d1) print(list(d2)) # ['a', 'b']

Errori tipici e anti-pattern

  • Utilizzo di un tipo mutabile come chiave (ad esempio, list o dict).
  • Errori nella copia: l'operatore semplice = non crea una copia, ma fa un nuovo "puntatore" allo stesso oggetto.
  • L'abuso di dict.get() senza controllare None può portare a errori imprevisti, se il valore == None.

Esempio della vita reale

Caso negativo

Il programmatore memorizza come chiavi delle liste, erroneamente ritenendo che tuple e list siano equivalenti come chiavi in Python. Riceve eccezioni di tipo "unhashable type".

Vantaggi:

Può provare rapidamente qualcosa "al volo", utilizzare qualsiasi struttura.

Svantaggi:

Errori di tempo di esecuzione, bug nel trattamento dei dati.

Caso positivo

Vengono utilizzati solo oggetti immutabili (hashabili) come chiavi, le tuple sono pensate per non contenere elementi mutabili.

Vantaggi:

Velocità di ricerca per chiave, affidabilità della struttura, facile elaborazione e copia.

Svantaggi:

Se i dati sono complessi, è necessaria una lavorazione aggiuntiva per portare la struttura a una forma immutabile (ad esempio, serializzazione all'interno di tuple).