haagn
haagn

Reputation: 163

Check if dictionary lists contain value and return keys

I have a dictionary with a set of key:value pairs where the values are a lists like so:

my_dict = {7: [6, 13], 6: [7, 8, 9, 11, 13, 14], 8: [6, 14], 9: [6], 11: [6], 13: [6, 7], 14: [6, 8]}

I want to check which of the lists contain the value '6' and return the keys which correspond to the matches. (i.e. 7, 8, 9, 11, 13 and 14)

I have tried the following code:

def find_key_for(input_dict, value):    
    for k, v in input_dict.items():
        if v == value:
            yield k
        else:
            return "None"

keys = list(find_key_for(my_dict, 6))

But it returns the following error:

ValueError: The truth value of an array with more than one element is ambiguous. Use a.any() or a.all()

How can I work around this issue to return all the keys whos lists contain this value? Thanks

Upvotes: 4

Views: 7096

Answers (3)

Calgary Michael
Calgary Michael

Reputation: 36

You are close!

dict.items() returns two things:

  • Key
  • Value

The value, in this instance, is a list. So essentially your implementation was doing this:

6 == [6, 14]

That is why you will be getting an empty list every single time. For short idiomatic code, go with the answer @Ajax1234 gave. However, if you want to guard against both lists and ints, do the following:

def find_key_for(input_dict, value):    
for k, v in input_dict.items():
    if value in v or value == v:
        yield k

I also want to note that you should not be using return in a generator. This return statement is redundant as [] would be the same thing

Upvotes: 2

Manur
Manur

Reputation: 8753

In your original code, I think the if line should be :

    if value in v:

Plus I'm not sure a generator is particularly useful here, since the laziness it offers is immediately canceled by the call being put in a list() call. One could do :

def find_key_for(input_dict, value):    
    result = []
    for k, v in input_dict.items():
        if value in v:
            result.append(k)
    return result

...which would then be easy to turn to a list comprehension.

Upvotes: 1

Ajax1234
Ajax1234

Reputation: 71451

You can use dict.items():

my_dict = {7: [6, 13], 6: [7, 8, 9, 11, 13, 14], 8: [6, 14], 9: [6], 11: [6], 13: [6, 7], 14: [6, 8]}
new_dict = [a for a, b in my_dict.items() if 6 in b]

Output:

[7, 8, 9, 11, 13, 14]

Upvotes: 9

Related Questions