Comment vérifier si une valeur existe dans un dictionnaire (python)

251

J'ai le dictionnaire suivant en python:

d = {'1': 'one', '3': 'three', '2': 'two', '5': 'five', '4': 'four'}

J'ai besoin d'un moyen de trouver si une valeur telle que "un" ou "deux" existe dans ce dictionnaire.

Par exemple, si je voulais savoir si l'index "1" existait, je devrais simplement taper:

"1" in d

Et puis python me dirait si c'est vrai ou faux, mais je dois faire exactement la même chose, sauf pour trouver si une valeur existe.

JimmyK
la source

Réponses:

381
>>> d = {'1': 'one', '3': 'three', '2': 'two', '5': 'five', '4': 'four'}
>>> 'one' in d.values()
True

Par curiosité, un timing comparatif:

>>> T(lambda : 'one' in d.itervalues()).repeat()
[0.28107285499572754, 0.29107213020324707, 0.27941107749938965]
>>> T(lambda : 'one' in d.values()).repeat()
[0.38303399085998535, 0.37257885932922363, 0.37096405029296875]
>>> T(lambda : 'one' in d.viewvalues()).repeat()
[0.32004380226135254, 0.31716084480285645, 0.3171098232269287]

EDIT: Et au cas où vous vous demandez pourquoi ... la raison en est que chacun des éléments ci-dessus renvoie un type d'objet différent, qui peut ou non convenir aux opérations de recherche:

>>> type(d.viewvalues())
<type 'dict_values'>
>>> type(d.values())
<type 'list'>
>>> type(d.itervalues())
<type 'dictionary-valueiterator'>

EDIT2: Selon la demande dans les commentaires ...

>>> T(lambda : 'four' in d.itervalues()).repeat()
[0.41178202629089355, 0.3959040641784668, 0.3970959186553955]
>>> T(lambda : 'four' in d.values()).repeat()
[0.4631338119506836, 0.43541407585144043, 0.4359898567199707]
>>> T(lambda : 'four' in d.viewvalues()).repeat()
[0.43414998054504395, 0.4213531017303467, 0.41684913635253906]
Mac
la source
je n'ai pas de python à portée de main, pourriez-vous relancer les tests avec «quatre» au lieu de «un»?
soulcheck
2
ce n'était pas nécessaire après tout, à moins de courir sur un dicton plus grand. Je suppose que la surcharge dans values ​​() est causée par la copie de la liste de valeurs et dans viewvalues ​​() en maintenant la vue vivante.
soulcheck
Étant donné la petite taille de d, les timings sont sans signification. En Python 3, dict.values()est une vue de dictionnaire, par défaut, et dict.itervalues()et dict.viewvalues()ont disparu. Vous pouvez tester à nouveau cela (avec un dictionnaire plus grand) et l'utiliser list(d.values())pour obtenir le comportement Python 2 et iter(d.values())pour obtenir le dict.itervalues()comportement, mais comme ces deux versions nécessitent une recherche et un appel globaux, elles seront absolument plus lentes. Les deux font un travail supplémentaire qui n'est pas nécessaire.
Martijn Pieters
33

Vous pouvez utiliser

"one" in d.itervalues()

pour tester si se "one"trouve parmi les valeurs de votre dictionnaire.

Sven Marnach
la source
22

Dictionnaire Python a get (clé) funcion

>>> d.get(key)

Par exemple,

>>> d = {'1': 'one', '3': 'three', '2': 'two', '5': 'five', '4': 'four'}
>>> d.get('3')
'three'
>>> d.get('10')
none

Si votre clé n'existe pas, retournera une nonevaleur.

foo = d[key] # raise error if key doesn't exist
foo = d.get(key) # return none if key doesn't exist

Contenu pertinent pour les versions inférieures à 3.0 et supérieures à 5.0. .

Shameem
la source
29
Ne répond pas à la question. OP a demandé une valeur comme dans key:valueet non clé.
akshaynagpal
10

Utilisez des vues de dictionnaire:

if x in d.viewvalues():
    dosomething()..
soulcheck
la source
4

Différents types pour vérifier les valeurs existent

d = {"key1":"value1", "key2":"value2"}
"value10" in d.values() 
>> False

Et si la liste des valeurs

test = {'key1': ['value4', 'value5', 'value6'], 'key2': ['value9'], 'key3': ['value6']}
"value4" in [x for v in test.values() for x in v]
>>True

Et si la liste de valeurs avec des valeurs de chaîne

test = {'key1': ['value4', 'value5', 'value6'], 'key2': ['value9'], 'key3': ['value6'], 'key5':'value10'}
values = test.values()
"value10" in [x for v in test.values() for x in v] or 'value10' in values
>>True
sim
la source
N'utilisez pas value in [... list comprehension over sequence ...], utilisez any(value in sequence ...), pour éviter de créer un objet de liste que vous n'utilisez pas pour autre chose, et pour court-circuiter lorsque la valeur a été trouvée.
Martijn Pieters
0

En Python 3, vous pouvez utiliser la values()fonction du dictionnaire. Il renvoie un objet de vue des valeurs. Ceci, à son tour, peut être passé à la iterfonction qui retourne un objet itérateur. L'itérateur peut être vérifié en utilisant in, comme ceci,

'one' in iter(d.values())

Ou vous pouvez utiliser l'objet de visualisation directement car il est similaire à une liste

'one' in d.values()
Reed Richards
la source
1
Il ne sert à rien d'utiliser iter()dans une vue de dictionnaire; inutilisera déjà l'objet comme un itérable (le type n'implémente pas de __contains__méthode dédiée ). La seule différence entre 'one' in iter(d.values())et 'one in d.values()est que vous avez fait faire du travail supplémentaire à Python (en payant le coût d'une recherche globale iter).
Martijn Pieters