4

I can't believe it, but I've been stumped by what should be a very simple task.

I need to check if a value is in a dictionary as either key or value. I can find keys using if 'A' in dictionary, however I can't seem to get this to work for values. I realise I could use a for loop to do this and I may resort to this but I was wondering if there is a built in method for it.

Anshul Goyal
  • 73,278
  • 37
  • 149
  • 186
Harvey
  • 384
  • 5
  • 15

4 Answers4

9

You can use in operator and any function like this

value in dictionary or any(value in dictionary[key] for key in dictionary)

Here, value in dictionary makes sure that the expression is evaluated to be Truthy if the value is one of the keys of dictionary

any(value in dictionary[key] for key in dictionary)

This part makes sure that, the value being searched is in any of the values in the dictionary.

Note: This approach is very efficient because

  1. you don't have to create any additional list in the memory

  2. any function short circuits, immediately after finding a match.

If you want to make sure that the value being searched should be exactly matched, then you can change the in to == like this

value in dictionary or any(value == dictionary[key] for key in dictionary)

As DSM Suggested, it would be better if we use value in dict.itervalues() in Python 2.x, value in dict.values() in Python 3.x

Community
  • 1
  • 1
thefourtheye
  • 233,700
  • 52
  • 457
  • 497
  • Downvoter, please let me know what is wrong. I believe this is the most efficient way. – thefourtheye Mar 30 '14 at 14:06
  • @Wooble I was already updating it. Please check the last two lines. – thefourtheye Mar 30 '14 at 14:10
  • @Wooble Also OP hasn't specified anything about the type of keys and values. – thefourtheye Mar 30 '14 at 14:11
  • @Wooble I knew that somebody would downvote with that exact reason, thats why I have included a way to fix that as well :) – thefourtheye Mar 30 '14 at 14:14
  • Well, considering all of the other answers don't use the constant-time check for the key that dicts give you and do an extra O(n) operation, this is definitely the best answer. – Wooble Mar 30 '14 at 14:23
  • 2
    I don't think your first answer using `in` matches what the OP is looking for, and instead of `any(value == dictionary[key] for key in dictionary)` wouldn't it be simpler to write `value in dictionary.itervalues()` in Python 2 or `value in dictionary.values()` in 3? Why use `any` with a genexp? – DSM Mar 30 '14 at 14:26
3

two easy ways:

my_keys = my_dict.keys()

my_keys is a list so you can then check for membership

my_values = my_dict.values()

same

if some_thing in my_keys
if some_thing in my_values

Of course you don't have to do that with keys though because with keys you can just ask

if some_thing in my_dict
PyNEwbie
  • 4,882
  • 4
  • 38
  • 86
3

I believe you are looking for d.values()

d.keys() is a list of dict keys (though what you were doing originally does the trick for keys)

d.values() is a list of the dict values. (You can test these for membership.)

where d is your dict

You can treat these as normal lists

There is also:

d.items() 

which is a list of tuples in the form (key, value) for each dict entry

example:

[(key, value), (key, value) ... ]

So testing for membership in d.keys() and d.values() with in is simple

With d.items() you could do:

for pair in d.items():
    if "A" in pair:
        do your thing

There is also d.iteritems() which you would use with for loop and I urge you to google.

Totem
  • 7,189
  • 5
  • 39
  • 66
3

You can do the following - i.e. combine all the keys, and the values within the dictionary into a new list and use the in keyword to find if value exists in it or not:

dict = {"a" : "b", "c" : "d"}

value = "b"

if value in dict.keys() + dict.values():
    print "present"
else: 
    print "absent"

You can optimize this further to the following, so that you use the in-built O(1) check for keys (from @Wooble's comment), and look for dictionary values only if the it is not in the keys

if value in dict or value in dict.values():
    print "present"

`

Anshul Goyal
  • 73,278
  • 37
  • 149
  • 186