HOWTO · Python

Trova chiave per valore nel dizionario Python

Questo tutorial mostra come ottenere la chiave per valore nel dizionario Python.

In questa pagina

I dizionari Python associano le chiavi ai valori, quindi per trovare una chiave partendo da un valore occorre cercare tra gli elementi del dizionario. Scorri ogni coppia chiave-valore e confronta il valore con quello cercato. Per ottenere la prima chiave corrispondente, usa un ciclo o next(); per ottenere tutte le chiavi corrispondenti, usa una list comprehension. La ricerca esamina gli elementi finché trova una corrispondenza o termina il dizionario.

Cerca le coppie chiave-valore con un ciclo

dict.items() fornisce un iterabile di coppie chiave-valore. Scorrerlo con un ciclo permette di restituire la prima chiave il cui valore è uguale a quello cercato. Restituire None al termine del ciclo comunica chiaramente che non è stata trovata alcuna corrispondenza; se None può essere una chiave valida, usa un valore sentinella distinto oppure restituisci una coppia (found, key).

Esegui questo esempio:

Il codice e le etichette o gli output visibili in questa sezione restano in inglese.

def find_key_by_value(dictionary, target):
    for key, value in dictionary.items():
        if value == target:
            return key
    return None

scores = {"Ada": 91, "Lin": 87, "Sam": 91}
print(find_key_by_value(scores, 87))
Lin

Il ciclo restituisce subito la chiave quando trova una corrispondenza, quindi restituisce la prima secondo l’ordine di iterazione del dizionario. Se più chiavi hanno il valore cercato, dopo la prima corrispondenza le successive non vengono esaminate.

Ottieni la prima chiave corrispondente con next()

Un’espressione generatrice consente di scrivere in modo conciso la stessa ricerca della prima corrispondenza. Passala a next() insieme a un valore predefinito: se il generatore non produce alcuna chiave corrispondente, la chiamata restituisce None invece di sollevare StopIteration.

Definisci il valore cercato come argomento della funzione che contiene l’espressione, così puoi usarla sia con un valore corrispondente sia con uno senza corrispondenze:

Il codice e le etichette o gli output visibili in questa sezione restano in inglese.

def find_key_with_next(dictionary, target):
    return next((key for key, value in dictionary.items() if value == target), None)

scores = {"Ada": 91, "Lin": 87, "Sam": 91}
print(find_key_with_next(scores, 87))
print(find_key_with_next(scores, 100))

Il generatore produce le chiavi man mano che servono, senza creare una lista di tutte le corrispondenze. Se nessun valore corrisponde, viene restituito il valore predefinito. Se i dati possono contenere None come chiave, scegli un valore predefinito che non possa essere confuso con una chiave valida.

Raccogli tutte le chiavi corrispondenti con una comprehension

Quando è importante considerare i valori duplicati, raccogli tutte le chiavi corrispondenti con una list comprehension:

Il codice e le etichette o gli output visibili in questa sezione restano in inglese.

def find_all_keys(dictionary, target):
    return [key for key, value in dictionary.items() if value == target]

scores = {"Ada": 91, "Lin": 87, "Sam": 91}
print(find_all_keys(scores, 91))
['Ada', 'Sam']

Se nessun valore corrisponde, la lista restituita è vuota; altrimenti contiene tutte le chiavi corrispondenti. Anche un’espressione filter() può selezionare le coppie chiave-valore corrispondenti, ma la comprehension rende visibili in un solo punto sia la condizione sia le chiavi raccolte.

Trova una chiave usando liste allineate di chiavi e valori

Un’altra possibilità consiste nel convertire dict.keys() e dict.values() in liste. Le posizioni corrispondono: la chiave in posizione i è associata al valore nella stessa posizione. Chiamando index() sulla lista dei valori si trova la prima posizione che contiene il valore cercato; usa poi quella posizione per selezionare la chiave dalla lista delle chiavi.

Il codice e le etichette o gli output visibili in questa sezione restano in inglese.

scores = {"Ada": 91, "Lin": 87, "Sam": 91}
keys = list(scores.keys())
values = list(scores.values())
position = values.index(91)
print(keys[position])
Ada

Se il valore è assente, index() solleva ValueError: controlla prima se il valore appartiene a values oppure gestisci l’eccezione quando è possibile che manchi. In presenza di valori duplicati, index() seleziona soltanto la prima posizione corrispondente.

Gestisci duplicati, valori mancanti e prestazioni

Scegli il tipo di risultato in base all’esigenza: un ciclo o next() restituisce una chiave, mentre la comprehension restituisce una lista di tutte le chiavi corrispondenti. I metodi che cercano la prima corrispondenza e index() si fermano al primo risultato; la chiave trovata dipende dall’ordine di iterazione del dizionario. Se non ci sono corrispondenze, si può ottenere None o una lista vuota; la tecnica con le liste allineate solleva invece ValueError, a meno che non si controlli la presenza del valore o si gestisca l’eccezione.

Nel caso peggiore, ciascuna di queste tecniche può esaminare tutti gli elementi: il tempo di ricerca è quindi proporzionale al numero di elementi del dizionario. Il ciclo e l’espressione generatrice non creano una raccolta di risultati. La comprehension crea una lista dei risultati, mentre la tecnica con le liste allineate crea prima liste separate di chiavi e valori. Se devi cercare ripetutamente una chiave a partire dal valore, valuta di mantenere una mappa inversa; considera però i valori duplicati, perché un semplice dizionario inverso conserva una sola chiave per ciascun valore. Per i dizionari annidati, stabilisci prima quale livello vuoi cercare e applica a quel dizionario lo stesso schema di iterazione sulle coppie.