3

Is there any way to use a dictionary as the key in a dictionary. Currently I am using two lists for this but it would be nice to use a dictionary. Here is what I currently am doing:

dicts = [{1:'a', 2:'b'}, {1:'b', 2:'a'}]
corresponding_name = ['normal', 'switcheroo']
if {1:'a', 2:'b'} in dicts:
    dict_loc = dicts.index({1:'a', 2:'b'})
    desired_name = corresponding_name[dict_loc]
    print desired_name

Here is what I want:

dict_dict = {{1:'a', 2:'b'}:'normal', {1:'b', 2:'a'}:'switcheroo'}
try: print dict_dict[{1:'a', 2:'b'}]
except: print "Doesn't exist"

But this does not work and I'm not sure if there's any way around this.

TheStrangeQuark
  • 2,257
  • 5
  • 31
  • 58
  • 1
    You can't use mutable objects as dictionary keys, so no. That is impossible. – zondo Jul 13 '16 at 01:53
  • Can't do that but you might find [named tuples](http://stackoverflow.com/questions/2970608/what-are-named-tuples-in-python) a good alternative – LinkBerest Jul 13 '16 at 01:59

3 Answers3

3

A dictionary key has to be immutable. A dictionary is mutable, and hence can't be used as a dictionary key. https://docs.python.org/2/faq/design.html#why-must-dictionary-keys-be-immutable

If you can guarantee that the dictionary items are also going to be immutable (ie. strings, tuples, etc), you could do this:

dict_dict = {}
dictionary_key = {1:'a', 2:'b'}
tuple_key = tuple(sorted(dictionary_key.items()))
dict_dict[tuple_key] = 'normal'

Essentially, we are converting each dictionary into a tuple, sorting the (key,value) pairs to ensure a consistent ordering within the tuple. We then use this tuple as the key to your dictionary.

Andrew Guy
  • 9,310
  • 3
  • 28
  • 40
  • It might be better to use an [`OrderedDict`](https://docs.python.org/3/library/collections.html#collections.OrderedDict) for this. That way OP doesn't have to remember to sort the dictionaries every time. – Pierce Darragh Jul 13 '16 at 02:13
3

As other answers have noted you can't use dictionaries as keys since keys need to be immutable. What you can do though is to turn a dictionary to a frozenset of (key, value) tuples which you can use as a key. This way you wouldn't have to worry about sorting and it would be more efficient as well:

dicts = [{1:'a', 2:'b'}, {1:'b', 2:'a'}]
corresponding_name = ['normal', 'switcheroo']

d = dict(zip((frozenset(x.iteritems()) for x in dicts), corresponding_name))

print d.get(frozenset({1:'a', 2:'b'}.iteritems()), "Doesn't exist")
print d.get(frozenset({'foo':'a', 2:'b'}.iteritems()), "Doesn't exist")

Output:

normal
Doesn't exist
niemmi
  • 17,113
  • 7
  • 35
  • 42
0

I guess this will help you

dicts = {
    'normal' : "we could initialize here, but we wont",
    'switcheroo' : None,
}
dicts['normal'] = {
    1 : 'a',
    2 : 'b',
}
dicts['switcheroo'] = {
    1:'b',
    2:'a'
}

if dicts.has_key('normal'):
    if dicts['normal'].has_key(1):
        print dicts['normal'][1]

print dicts['switcheroo'][2]
Nilo Araujo
  • 725
  • 6
  • 15