Jannik Jannik - 6 months ago 27
JSON Question

Converting/Serializing dictionaries containing a large list of value pairs into a json file in python

Currently I try to convert data from an ESRI shapefile (.shp) to a Json file using the json package.

In this process, I want to convert a dictionairy containing the coordinates of a lot of different points:

json.dumps({"Points" : coordinates})

The list "coordinates" looks like:

[[-2244.677490234375, -3717.6876220703125], [-2252.7623006509266, -3717.321774721159],
..., [-2244.677490234375, -3717.6876220703125]]

and contains about several hundreds of coordinate pairs.

However, when I try to execute json.dumps, I get the following error:

[-2244.677490234375, -3717.6876220703125] is not JSON serializable

My first thought was, that it can not handle decimal/float values But if I execute the following working example containing only two of the coordinate pairs:

print(json.dumps({"Points" : [[-2244.677490234375, -3717.6876220703125],
[-2244.677490234375, -3717.6876220703125]]}))

tt works and I do not get an error... The output in this case is:

{"Points": [[-2244.677490234375, -3717.6876220703125], [-2244.677490234375, -3717.6876220703125]]}

I don't get why it isn't working with my "coordinates"-list.


The error you are seeing most commonly happens with custom classes. So I believe your problem has to do with the way pyshp is supplying the coordinate values. I can't be sure without seeing your code, but looking at the pyshp source I found an _Array class that is used in a few places.

class _Array(array.array):
  """Converts python tuples to lits of the appropritate type.
  Used to unpack different shapefile header parts."""
  def __repr__(self):
    return str(self.tolist())

The __repr__ might explain why you believe you are seeing a standard list or tuple when in fact it is a custom class. I put together a python fiddle which demonstrates the exception when providing pyshp's _Array class to json.dumps().

To fix this issue you should pass coordinates.tolist() to your dumps call.

json.dumps({"Points" : coordinates.tolist()})