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.

6
  • i think you can just omit bool:, int:, str: to make it simpler. Commented Jan 25, 2017 at 20:16
  • I suppose that you could do bool(False), int(42) and use eval. Commented Jan 25, 2017 at 20:16
  • can you just do {str(k): v for k, v in d.items()} Commented Jan 25, 2017 at 20:16
  • 1
    For JSON, not that I know of. You could instead use msgpack or some other format that works the way you want. Commented Jan 25, 2017 at 20:16
  • Here's some discussion that you may find valuable stackoverflow.com/q/1450957/1916449 Commented Jan 25, 2017 at 20:46

3 Answers 3

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}
Sign up to request clarification or add additional context in comments.

2 Comments

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.
"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.
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.

1 Comment

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.
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

1 Comment

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.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.