1

I have looked for an answer on SO, however no answer was particulary useful. I have a dictionary of values that I have to convert to JSON string. The data looks like this:

In [127]: ddd
Out[127]: 
{'ID': {'condition': '',
  'data': {1: '2',
   2: '3',
   3: '4',
   4: '5',
   5: '6',
   6: '7',
   7: '8',
   8: '9',
   9: '10'},
  'desc_long': 'Id szko\xc5\x82y',
  'desc_short': 'Id szko\xc5\x82y',
  'df_name': 'pierszytest',
}}

When I try to execute json.dumps(ddd) I get :

TypeError: keys must be a string

I created a test variable "what"

In [126]: what
Out[126]: {1: '2', 2: '3', 3: '4', 4: '5', 5: '6', 6: '7', 7: '8', 8: '9', 9: '10'}

json.dumps(what) returns:

Out[129]: '{"1": "2", "2": "3", "3": "4", "4": "5", "5": "6", "6": "7", "7": "8", "8": "9", "9": "10"}'

Again, I tried to convert only ddd['ID']['data']:

 In [131]: ddd['ID']['data']
 Out[131]: {1: '2', 2: '3', 3: '4', 4: '5', 5: '6', 6: '7', 7: '8', 8: '9', 9: '10'}

 In [130]: json.dumps(ddd['ID']['data'])

 TypeError: keys must be a string

So, this are basically the same variables and still json.dumps fails to deal with the latter. This is a big surpise for me. I have done some research, but it returned nothing useful for my case. If it's a duplicate, please let me know.

* EDIT * I attach result of type() on both variables:

In [132]: type(ddd['ID']['data'])
Out[132]: dict

In [133]: type(what)
Out[133]: dict
3
  • What is type(ddd['ID']['data'])? And can you include the definition of that type in the question, or at least link to it? Commented Jul 5, 2013 at 11:01
  • I have edited the question to attach result of running "type" on both variables Commented Jul 5, 2013 at 11:22
  • 1
    The problem is that the keys are numpy objects. See my updated answer for a solution. Commented Jul 5, 2013 at 12:50

2 Answers 2

1

The error message is correct; keys in JSON objects must be strings, according to the JSON standard:

object = begin-object [ member *( value-separator member ) ]
         end-object
member = string name-separator value

Therefore, either choose another format than JSON, or let your keys be strings. In your case, you want to convert numpy.int64 variables to strings; try the following:

# This paragraph is just for testing, replace it with your actual code
import pandas  as pd
import numpy as np
d = pd.Series([1,3,5,np.nan,6,8]).to_dict()
ddd = {'ID': {'DATA': d}}


import json
import copy
def _convert(dct):
    return dict((str(k),v) for k, v in dct.items())
ddd_json = copy.deepcopy(ddd)
ddd_json['ID']['data'] = _convert(ddd_json['ID']['data'])

print(json.dumps(ddd_json, indent=2))
Sign up to request clarification or add additional context in comments.

Comments

1

In fact Json needs as key a string. Is mandatory that they keys must be an integer? Just take this into account when you tray to deserialize the json an manage type conversion.

When deserializing: int(key) to get agin the integer. I supose is posible.

5 Comments

They don't have to be integers, however look at the comparison between ddd['ID']['data'] and what. They're both dicts, so the issue must be laying deeper than that. I don't have to actually use integer type for the keys, that's the return format of pandas.DataFrame.to_dict() function. I can convert it of course, however, I want to understand that and also I don't want to do the conversion unless it's the only way to deal with this problem. I don't understand why it works with one var and doesn't with the other.
well, actually a copied and pasted your code, and it serialised correctly on my python shell. json.dumps(ddd['ID']['data']) '{"1": "2", "2": "3", "3": "4", "4": "5", "5": "6", "6": "7", "7": "8", "8": "9", "9": "10"}'
yes, I have copied and pasted it too and it works, however, when I retrieve data from pandas.DataFrame.to_dict() it fails to serialize. How strange is that?
As @phihag sugested, check the types that pandas.DataFrame.to_dict() is returning. The only thing come tu my mind is that actually what you will use as key, is not even an integer... in that case you probably will need to write the custom method he suggested.
Thanks, I will investigate this further. As of now, I just converted keys to string as a temporay workaround. However, I am beware of a constant nature of temporary workarounds. Thanks for helping me out here.

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.