简体   繁体   中英

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

I am trying to frame a data structure to do the following operation.

I want a key-value pair that looks 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 dict object when color is red, shape is circle. Return a different json style dict object when color is blue, shape is square etc.

So, my key is not really a regular key. It is kind of a composite key. Please suggest

This can't be done in Python. You'll receive a TypeError . The reason for this is that a dictionary key must be a hashable object, which a dict is not. As an example, try this:

>>> 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 that dict s are not hashable is that they are mutable objects. This means (roughly) that they can change (although it's 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 isn't hashable, it can't be used as a key. See the Data Model section of the Python docs for more information on mutable and immutable objects.

As others have said, you should use an immutable object, such as a tuple or a 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, neither does Python since dict objects are not hashable. I'd go for a namedtuple in this case, since you will (hopefully) know up-front what constituents your key will have:

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

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

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM