HOWTO · Python
Tabella di ricerca in Python
Questo tutorial dimostra come utilizzare le tabelle di ricerca in Python, evidenziando metodi come dizionari, liste, array NumPy e DataFrame Pandas. Impara a implementare tecniche di recupero dati efficienti per ottimizzare le tue abilità di programmazione e migliorare le prestazioni delle applicazioni. Esplora esempi di codice pratici e spiegazioni dettagliate per padroneggiare le tabelle di ricerca in Python.
In questa pagina
Una tabella di ricerca memorizza valori che il codice può recuperare tramite una chiave o una posizione. È utile quando si consulta ripetutamente la stessa relazione, per esempio per associare i codici dei prodotti ai prezzi. Calcolare un risultato in anticipo può evitare di ripetere un calcolo, ma la tabella occupa memoria e va aggiornata quando cambiano i dati di origine.
Scegli la struttura in base alla forma delle chiavi e alle operazioni necessarie: i dizionari accettano chiavi hashable arbitrarie, le liste e gli array usano posizioni intere, mentre un DataFrame supporta colonne con etichette e operazioni tabellari. Gli esempi mostrano come ciascuna struttura gestisce una ricerca pratica.
Scegliere una struttura per la tabella di ricerca
Per prima cosa, chiediti che cosa identifica un valore. Usa un dizionario per nomi, codici o altre chiavi che non corrispondono a posizioni intere dense. Usa una lista quando le posizioni sono interi consecutivi a partire da zero e i valori possono essere contenuti in una sequenza Python. Scegli un array NumPy se i dati sono numerici e ti servono operazioni sugli array. Usa un DataFrame Pandas quando ogni record contiene più campi con nome oppure ti servono filtri e altre operazioni tabellari. NumPy e Pandas sono dipendenze di terze parti: installale nell’ambiente del progetto prima di usare i relativi esempi.
Usare un dizionario per le ricerche basate su chiavi
Un dizionario associa ogni chiave hashable distinta a un valore. È adatto alle chiavi non sequenziali e consente di specificare chiaramente un valore alternativo con get. Se la chiave non è presente, get restituisce il valore predefinito indicato; l’accesso con parentesi quadre, invece, genera KeyError quando la chiave manca.
Esegui questo esempio. Il codice e le etichette o gli output visibili restano in inglese.
prices = {"tea": 2.5, "coffee": 3.0, "cocoa": 2.75}
print(prices["tea"])
print(prices.get("juice", "not listed"))
2.5
not listed
Il recupero da un dizionario ha complessità O(1) nel caso medio, ma questo non è garantito per ogni carico di lavoro. Le chiavi devono essere hashable e assegnare un valore a una chiave esistente sostituisce quello precedente. Se cambiano i record di origine, aggiorna anche il dizionario per evitare che la ricerca restituisca dati obsoleti.
Usare una lista per indici interi densi
Una lista è una tabella semplice quando gli indici validi sono densi e partono da zero: l’indice i indica l’elemento (i + 1)-esimo. È poco adatta a identificativi sparsi, come i numeri dei clienti, perché gli intervalli vuoti richiederebbero posizioni inutilizzate o una mappatura separata. L’accesso tramite indice ha complessità O(1); i valori restano normali oggetti Python.
Il codice e le etichette o gli output visibili in questa sezione restano in inglese.
labels = ["bronze", "silver", "gold"]
def label_for(index):
if 0 <= index < len(labels):
return labels[index]
return "index out of range"
print(label_for(2))
print(label_for(5))
gold
index out of range
Il controllo esplicito dell’intervallo gestisce sia gli indici inferiori a zero sia quelli pari o superiori alla lunghezza della lista. Le liste Python accettano anche indici negativi, che contano a ritroso dalla fine: convalida quindi l’indice prima dell’accesso se le chiavi della tabella sono definite solo come posizioni non negative.
Usare un array NumPy per dati numerici
Un array NumPy è utile quando la tabella contiene valori numerici e servono anche calcoli vettorializzati, sezionamenti o altre operazioni sugli array. NumPy va installato separatamente: non fa parte della libreria standard di Python. Una ricerca di un singolo valore resta un semplice accesso tramite indice, quindi un array non è automaticamente più veloce di un dizionario.
Il codice e le etichette o gli output visibili in questa sezione restano in inglese.
import numpy as np
rates = np.array([1.0, 1.5, 2.0, 2.5])
index = 2
if 0 <= index < len(rates):
print(rates[index])
else:
print("index out of range")
print((rates * 2).tolist())
2.0
[2.0, 3.0, 4.0, 5.0]
Il controllo dei limiti è utile quando un indice proviene da dati esterni. In genere gli array NumPy usano un solo tipo di elemento, caratteristica che può semplificare le operazioni numeriche; scegli il tipo e la forma dell’array in base ai dati da memorizzare.
Usare un DataFrame Pandas per dati tabellari
Un DataFrame è adatto a record con colonne dotate di nome, soprattutto quando la ricerca fa parte di un’attività più ampia di filtraggio o analisi. Pandas va installato separatamente. Il filtro su una colonna confronta le righe e, se selezioni solo le righe, restituisce un DataFrame. Nell’espressione seguente, selezionare con .loc la singola colonna price restituisce una Series; il filtro può esaminare le righe. Per ricerche ripetute tramite chiave, valuta di impostare un indice significativo e usare .loc.
Il codice e le etichette o gli output visibili in questa sezione restano in inglese.
import pandas as pd
items = pd.DataFrame({
"code": ["A", "B", "C"],
"price": [1.25, 2.50, 3.75],
})
match = items.loc[items["code"] == "B", "price"]
if not match.empty:
print(match.iloc[0])
else:
print("not found")
2.5
Questo schema gestisce l’assenza di un codice corrispondente senza tentare di accedere a un risultato vuoto. Se i codici sono univoci e vengono cercati ripetutamente, items.set_index("code").loc["B", "price"] esprime una ricerca tramite etichetta; verifica che il codice esista prima di accedervi e decidi come gestire eventuali etichette duplicate.
Gestire chiavi mancanti e indici non validi
Scegli una politica per i valori mancanti adatta a chi usa la funzione. dict.get(key, default) restituisce un valore alternativo, mentre key in mapping permette di distinguere l’assenza della chiave da un valore memorizzato che coincide per caso con quello alternativo. Usa try/except KeyError quando, nella logica circostante, l’assenza di una chiave è un’eccezione. Per liste e array, verifica l’indice con 0 <= index < len(table) se le posizioni negative non devono contare a ritroso dalla fine. Per un filtro su un DataFrame, controlla che il risultato non sia vuoto prima di selezionarne la prima riga. Mantieni la stessa politica tra le funzioni, così chi le usa sa se l’assenza restituisce un valore sentinella, un valore predefinito o un errore.
Confrontare prestazioni e compromessi pratici
La ricerca in un dizionario tramite chiave ha complessità O(1) nel caso medio; una lista o un array monodimensionale ha complessità O(1) per l’accesso tramite posizione. In genere, un filtro booleano su un DataFrame ha complessità O(n), perché esamina le righe. Un indice può supportare l’accesso tramite etichetta, ma costo e comportamento dipendono dalla sua costruzione e dalla forma dei dati. Queste descrizioni della complessità non permettono di prevedere il tempo effettivo per ogni dimensione dell’input: contano anche i costi di preparazione, i tipi delle chiavi, la disposizione dei dati, le operazioni della libreria e la memoria.
Scegli la struttura più semplice che corrisponde alle chiavi e alle operazioni necessarie: dizionario per chiavi arbitrarie, lista per posizioni dense, array NumPy per operazioni numeriche sugli array e DataFrame per dati tabellari con etichette. Se le prestazioni sono decisive, misura il comportamento su dati rappresentativi. Considera anche la memoria: i dizionari memorizzano associazioni chiave-valore, le liste contengono riferimenti a oggetti Python e gli array NumPy memorizzano elementi tipizzati; l’uso effettivo dipende dai dati e dall’implementazione. Se una tabella di ricerca deriva da dati di origine soggetti a modifiche, ricostruiscila o aggiornala ogni volta che tali dati cambiano, così da evitare risultati obsoleti.