-1

I have a dictionary in python like this:

 CS_i = {'C_S1': ['v3', 'v4'], 'C_S3': ['v1'], 'C_S2': ['v2', 'v5']}

and I want to access the keys by each of their values. For example, I want to get C_S1 by v3. Does anybody know how can I do that?

ayhan
  • 70,170
  • 20
  • 182
  • 203
Amir
  • 53
  • 4
  • 2
    Possible duplicate of [Inverse dictionary lookup in Python](https://stackoverflow.com/questions/2568673/inverse-dictionary-lookup-in-python) – ayhan Oct 02 '17 at 05:35

2 Answers2

0

Assuming your dictionary may have duplicate values under multiple keys, you could use

def vToKeys(dictionary, value): # return keys that dictionary[key] contain value
    return [ key for key, x in dictionary.items() if value in x ]

print(vToKeys(CS_i, 'v3'))

if just need the first or only match

def vToKeys(dictionary, value): # return keys that dictionary[key] contain value
    return [ key for key, x in dictionary.items() if value in x ]

print(vToKeys(CS_i, 'v3')[0])
professor.jenkins
  • 155
  • 1
  • 1
  • 8
  • Your second,' first or only match' example, shows how comprehensions lure us into bad habits as it keeps searching even after the answer is known. A conventional loop with a `break` would seem more appropriate here. Also, searching for a value that's not in the dictionary causes this single key solution to blow up with `IndexError: list index out of range`. – cdlane Oct 02 '17 at 06:22
  • you are right that my list comprehension solution is flawed for a list that goes way beyond the size of the first 10 non-zero values. – professor.jenkins Oct 02 '17 at 07:04
  • Thank you very much, you gave me some hints, It worked well with some changes. – Amir Oct 02 '17 at 07:07
0

You need to face two issues: 1) the value you're reverse looking up may occur more than once and so you'll need to have unique values or decide what you want to do in that situation and 2) the value may not exist in the dictionary so you'll want to handle a None result.

A simple solution:

CS_i = {'C_S1': ['v3', 'v4'], 'C_S3': ['v1'], 'C_S2': ['v2', 'v5']}

def getkey(dictionary, value):
    for key, values in dictionary.items():
        if value in values:
            return key

    return None

print(getkey(CS_i, 'v3'))

However, if you call getkey() often enough, you'll want to consider inverting the entire dictionary and use the inversion instead:

def invertdict(dictionary):
    inverted = dict()

    for key, values in dictionary.items():
        for value in values:
            inverted[value] = key

    return inverted

CS_i_inverted = invertdict(CS_i)

print(CS_i_inverted['v3'])

You'll need unique values for this to work correctly.

cdlane
  • 40,441
  • 5
  • 32
  • 81