Converting JSON String to Dictionary Not List

lawchit picture lawchit · Oct 20, 2013 · Viewed 541.9k times · Source

I am trying to pass in a JSON file and convert the data into a dictionary.

So far, this is what I have done:

import json
json1_file = open('json1')
json1_str = json1_file.read()
json1_data = json.loads(json1_str)

I'm expecting json1_data to be a dict type but it actually comes out as a list type when I check it with type(json1_data).

What am I missing? I need this to be a dictionary so I can access one of the keys.

Answer

DaoWen picture DaoWen · Oct 21, 2013

Your JSON is an array with a single object inside, so when you read it in you get a list with a dictionary inside. You can access your dictionary by accessing item 0 in the list, as shown below:

json1_data = json.loads(json1_str)[0]

Now you can access the data stored in datapoints just as you were expecting:

datapoints = json1_data['datapoints']

I have one more question if anyone can bite: I am trying to take the average of the first elements in these datapoints(i.e. datapoints[0][0]). Just to list them, I tried doing datapoints[0:5][0] but all I get is the first datapoint with both elements as opposed to wanting to get the first 5 datapoints containing only the first element. Is there a way to do this?

datapoints[0:5][0] doesn't do what you're expecting. datapoints[0:5] returns a new list slice containing just the first 5 elements, and then adding [0] on the end of it will take just the first element from that resulting list slice. What you need to use to get the result you want is a list comprehension:

[p[0] for p in datapoints[0:5]]

Here's a simple way to calculate the mean:

sum(p[0] for p in datapoints[0:5])/5. # Result is 35.8

If you're willing to install NumPy, then it's even easier:

import numpy
json1_file = open('json1')
json1_str = json1_file.read()
json1_data = json.loads(json1_str)[0]
datapoints = numpy.array(json1_data['datapoints'])
avg = datapoints[0:5,0].mean()
# avg is now 35.8

Using the , operator with the slicing syntax for NumPy's arrays has the behavior you were originally expecting with the list slices.