2

The JSON equivalent of a Python dict is a JSON object. However its keys must be strings, that's a well-known limitation.

I need to support also boolean and numeric keys. I could make a simple Python value <--> JSON string one-to-one translation:

False <--> "bool:False"
42 <--> "int:42"
"Foo" <--> "str:Foo"

But I'd like to ask if there is some existing recommendation or some kind of standard for this. Simply anything that it is worth to be compatible with.

VPfB
  • 14,927
  • 6
  • 41
  • 75

3 Answers3

1

JSON isn't able to do that and I don't know of any widely-used extensions of JSON that allow you to do this. You'd have to write the serializer and deserializer yourself, which probably wouldn't be that difficult if you subclass json.JSONEncoder and json.JSONDecoder.

If you're able to switch protocols, there are JSON-ish protocols that support non-string keys. MessagePack is one:

>>> import msgpack
>>> msgpack.loads(msgpack.dumps({'1': 12, False: 3, 2: 8}))
{False: 3, 2: 8, '1': 12}
Blender
  • 289,723
  • 53
  • 439
  • 496
  • Thank you for your suggestion.This time I need to make a change as small as possible to an existing system, so I must stay with JSON. +1 because I learned someting new. – VPfB Jan 25 '17 at 21:14
  • "_I don't know of any widely-used extensions of JSON that allow you to do this_" is accepted as a direct answer to my question. – VPfB Jan 26 '17 at 11:16
0

This would achieve what you want:

>>> import json
>>> data = {False: 'this data', 42: 'answer', 'foo': 'bar'}
>>> json.dumps({"%s:%s" % (type(k).__name__, k): v for k, v in data.items()})
'{"int:42": "answer", "str:foo": "bar", "bool:False": "this data"}'

You'd then have to de-serialize this, and it would only work for basic types.

Rafael Barros
  • 2,738
  • 1
  • 21
  • 28
  • Yes, something like this will do. However there are many possible variations. I just wanted to know, if some format is already in use or otherwise preferred. It looks like the answer is negative, but that's a valid answer. – VPfB Jan 25 '17 at 21:24
0

Since you cannot issue standard JSON, why don't you just use str to serialize and ast.literal_eval (standard package) to deserialize?

>>> d = {'a': 33, 23:(4,5), False: 10, 4: "foo"}
>>> a = str(d)   # convert the python structure to a string
>>> d2 = ast.literal_eval(a)
>>> print(d2)  # evaluate the a literal to a python structure
{False: 10, 4: 'foo', 'a': 33, 23: (4, 5)}
>>> d2 == d   # are those the same before & after evaluation ?
True
Jean-François Fabre
  • 137,073
  • 23
  • 153
  • 219
  • Thank you for your suggestion.This time I need to make a change as small as possible to an existing system, so I must stay with JSON. – VPfB Jan 25 '17 at 21:15