0

I'm using Python 3. I have 3 groups and in these groups I have multiple values. enter image description here

I have the value that I search and I want to get his group. For example if I have CCC I need to get GROUP 1 and if I have HHH I want the GROUP 3 then do something according to the group.

So I think I gonna create a dict like this (tell me if I'm wrong) :

{
  'group1': {'AAA','BBB','CCC','DDD'}, 
  'group2': {'EEE','FFF','GGG'},
  'group3': {'HHH','JJJ'}
}

So I see that we can revert the dict to get the key from a value so I thought to do this :

dict = {
  'group1': {'AAA','BBB','CCC','DDD'},
  'group2': {'EEE','FFF','GGG'},
  'group3': {'HHH','JJJ'}
}

revdict = dict([(dict[key],key) for key in dict])

group = revdict['CCC']
if group == 'group1':
    # Do something
elif group == 'group2':
    # Do something
elif group == 'group3':
    # Do something

But I don't think it's the good way to do what I want. There is a way to do something like this :

if 'CCC' in dict :
    # Then get the current key. How ?

Or maybe I don't need to create dict but another things ? I open for all your suggestions.

John
  • 4,711
  • 9
  • 51
  • 101
  • I don't see anything wrong with your `revdict` solution. It can do everything you want. What's the problem? – Aran-Fey Oct 04 '18 at 13:01
  • 1
    Possible duplicate of [How to get all keys from dictionary from a value?](https://stackoverflow.com/questions/52643037/how-to-get-all-keys-from-dictionary-from-a-value) – deadvoid Oct 04 '18 at 13:04
  • Because I don't know if this is a good solution. I don't know if revdict will slow down my script. – John Oct 04 '18 at 13:07
  • @Aran-Fey In fact the reverse dict willl not work because I have multiple values for 1 key so I'll get `TypeError: unhashable type: 'set'` – John Oct 04 '18 at 13:21
  • Ok, but if you invert the dict *correctly*, that would solve all your problems? – Aran-Fey Oct 04 '18 at 13:33

4 Answers4

1

Your reversed dict, commonly called an inverted index, will fail because you are using sets as keys. Sets being mutable, they cannot be hashed to form a dict key. Instead, you probably wanted each element of a group to form a key.

You can rewrite the correct inverted index with a defaultdict.

from collections import defaultdict

groups = {
    'group1': {'AAA', 'BBB', 'CCC', 'DDD'},
    'group2': {'EEE', 'FFF', 'GGG'},
    'group3': {'HHH', 'JJJ'}
}

inverted_index = defaultdict(set)

for name, group in groups.items():
    for element in group:
        inverted_index[element].add(name)

print('group1' in inverted_index['AAA']) # True
print('group1' in inverted_index['EEE']) # False

In an inverted index, an element may have multiple keys pointing to it (even though it is not the case in you data), this is why each value must be a set of keys.

If, as you seem to state it in the comments, your data is assured to only have one-to-one correspondences, then you can simply create a dict.

inverted_index = {element: name for name, group in groups.items() for element in group}
print(inverted_index)

Output

{'AAA': 'group1',
 'BBB': 'group1',
 'CCC': 'group1',
 'DDD': 'group1',
 'EEE': 'group2',
 'FFF': 'group2',
 'GGG': 'group2',
 'HHH': 'group3',
 'JJJ': 'group3'}
Olivier Melançon
  • 21,584
  • 4
  • 41
  • 73
  • Ok I see. But if I do `print(inverted_index['AAA'])` it returns `{'group1'}` how can I get just the string `group1`? – John Oct 04 '18 at 13:29
  • @John You do not want to do that. Since it may be that multiple keys are associated to a value. Having a single key associated to, say 'AAA', would overwrite any other found key. – Olivier Melançon Oct 04 '18 at 13:30
  • Maybe I just have to create manually the good dict ? `d = {'AAA' : 'group1', 'BBB' : 'group1', 'EEE' : 'group2'}` etc... – John Oct 04 '18 at 13:34
  • @John No. The way I suggested can very easily be adapted to create a one-to-one inverted index. Do you understand what I mean when I say it's a bad idea? – Olivier Melançon Oct 04 '18 at 13:35
  • @John I added the ouput format you wanted. Please make sure to understand what I am saying about one-to-one corresponce. Otherwise, it will eventually blow in your face when an element will be allowed to be in multiple groups. – Olivier Melançon Oct 04 '18 at 13:39
  • But the output is the same as I wrote in my previous comment. Btw it's impossible that an element will be allowed to be in multiple groups. They are static – John Oct 04 '18 at 13:44
  • @John Good if you are sure an element cannot be in multiple groups, the second solution is what you want – Olivier Melançon Oct 04 '18 at 13:46
  • 1
    Ok. But you're right if elements are not static your first solution is nice – John Oct 04 '18 at 13:48
0

You can retrieve the key using list comprehension and only returning the key if the str you are looking for is in its values

d = {
  'group1': {'AAA','BBB','CCC','DDD'},
  'group2': {'EEE','FFF','GGG'},
  'group3': {'HHH','JJJ'}
}

a = [i for i in d if 'CCC' in d[i]]
# ['group1']
vash_the_stampede
  • 4,590
  • 1
  • 8
  • 20
  • How can I do to get just the string and not `['group1']` without add [0] at the end ? – John Oct 04 '18 at 13:20
0

I you insist on not using index for the key,

answer = None
for key in d.keys():
   if "CCC" in d[key]:
      answer = key
      break

*edit suggested by @Olivier

GraphicalDot
  • 2,644
  • 2
  • 28
  • 43
0
for k,v in dict.items():
   if 'CCC' in v:
      print(k)

you can't escape loops or reverse dicts. if you don't have memory constraints use your reverse dict.