Tim
Tim

Reputation: 583

Get keys by list of values

I have a dictionary and a list of values such as:

dictionary = {'a': 1, 'b': 2, 'c': 3, 'd': 4}

liste = [2, 3]

I would like:

result = ['b', 'c']

If I have a very large dictionary, what is the most optimal way to do this?

The keys have unique values.

Upvotes: 0

Views: 238

Answers (3)

Max Shouman
Max Shouman

Reputation: 1331

Lookup by value is exactly what dictionaries are not meant for.

Since you said the dictionary is very large, the most efficient solution relies on how many times you're operating on it.

If it's going to be a frequent task, you may need to create a reverse dictionary. This can be done comprehensively:

rev_dict = {v: k for k, v in dictionary.items()}

Then you can lookup the dictionary the way it's designed for.

On the contrary, an isolated case does not justify creating a copy of a very large dictionary, which can be memory and time consuming. So I came up with this awful messy un-Pythonic construct, which exploits the ordered feature of Python 3.7+ dictionaries:

list(dictionary.keys())[list(dictionary.values()).index(your_value)]

Mind you, use this only if you're desperate.

Obviously, the best solution is the one everybody knows but no-one wants: hardcode a reverse dictionary before running the script.

This can also bring some issues to your attention that the above solutions are unable to avoid at runtime (not without being explicitly handled), e.g. reversing your dict may result in having duplicate keys, which is not illegal, but will result in a sadly shortened dictionary.

Upvotes: 0

Saurabh Sangwan
Saurabh Sangwan

Reputation: 427

The idea here is to create a reverse_dict for an efficient lookup, otherwise the complexity can be O(mn), m-number of keys, n-length of liste. A value can be duplicate, so keeping a list for the keys is also important.

result = []
reverse_dict = collections.defaultdict(list)
for key, value in dictionary.items():
    reverse_dict[value].append(key) 
for v in liste:
    result.extend(reverse_dict[v])

Upvotes: 6

zr0gravity7
zr0gravity7

Reputation: 3204

dictionary = {'a': 1, 'b': 2, 'c': 3, 'd': 4}

liste = [2, 3]

result = []
for key, value in dictionary.items():
    if value in liste:
        result.append(key)

As a list comprehension:

result = [key for key, value in dictionary.items() if value in liste]

Upvotes: 2

Related Questions