Use dict as composite key of another python python (key-value pair)

I am trying to create a data structure to perform the following operation.

I want a key-value pair to look something like this.

  {"color": "red", "shape": "circle"}: {data: [{}, {}, {}, {}]}
, {"color": "blue", "shape": "square"}: {data: [{}, {}, {}, {}]}
, {"color": "blue", "shape": "circle"}: {data: [{}, {}, {}, {}]}
, {"color": "red", "shape": "square"}: {data: [{}, {}, {}, {}]}


What I want is to return a json style object when the color is red the shape is circle. Return another json style object when color is blue, shape is square, etc.

So my key is not a regular key. It's kind of a tricky key. Please suggest


source to share

3 answers

This cannot be done in Python. You will receive TypeError

. The reason for this is that the dictionary key must be a hashable object, dict

not. Try this as an example:

>>> d0 = {'foo': 'bar',}
>>> assert d0 == {'foo': 'bar'}
>>> d1 = {d0: 'baz',}
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: unhashable type: 'dict'
>>> hash(d0)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: unhashable type: 'dict'


The reason dict

not hashing is because they are mutable objects. This means (roughly) that they can change (although this is a little more subtle than that, to quote the Python docs). IIRC, under the hood, Python uses hash tables to implement dictionary keys, so if an object is not hashable it cannot be used as a key. See the Data Model section in the Python docs for more information on mutable and immutable objects.

As others have said, you should use an immutable object like a tuple or namedtuple for your key:

>>> from collections import namedtuple
>>> colors = 'red blue'.split(' ')
>>> shapes = 'circle square'.split(' ')
>>> Figure = namedtuple('Figure', ('color', 'shape'))
>>> my_dict = {Figure(color, shape): {'data': [{}, {}, {}, {},]}
...            for color in colors for shape in shapes}
>>> assert my_dict == {Figure(color='blue', shape='circle'): {'data': [{}, {}, {}, {}]}, Figure(color='blue', shape='square'): {'data': [{}, {}, {}, {}]}, Figure(color='red', shape='circle'): {'data': [{}, {}, {}, {}]}, Figure(color='red',shape='square'): {'data': [{}, {}, {}, {}]}}
>>> assert my_dict[('blue', 'circle')] == {'data': [{}, {}, {}, {}]}




JSON does not support what you are looking for and Python as objects are dict

not hashed. I would go for it namedtuple

in this case, since you (hopefully) know what constituents you will have your key:

from collections import namedtuple
MyKey = namedtuple("MyKey", "color shape".split())

my_dict = {
   MyKey(color="red", shape="circle"): {...}




You cannot use a dict object as a key in python. I would like to use something immutable as a key: instead of the dict object itself, I use its string representation.



All Articles