Преобразование / сериализация словарей, содержащих большой список пар значений, в файл json на python

В настоящее время я пытаюсь преобразовать данные из шейп-файла ESRI (.shp) в файл Json, используя пакет json.

В этом процессе я хочу преобразовать словарь, содержащий координаты множества разных точек:

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

Список "координаты" выглядит так:

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

и содержит около нескольких сотен координатных пар.

Однако, когда я пытаюсь выполнить json.dumps, я получаю следующую ошибку:

[-2244.677490234375, -3717.6876220703125] is not JSON serializable

Моей первой мыслью было, что он не может обрабатывать десятичные / плавающие значения. Но если я выполню следующий рабочий пример, содержащий только две пары координат:

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

ТТ работает, и я не получаю ошибку... Вывод в этом случае:

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

Я не понимаю, почему он не работает с моим списком "координат".

1 ответ

Решение

Ошибка, которую вы видите чаще всего, происходит с пользовательскими классами. Поэтому я считаю, что ваша проблема связана с тем, как pyshp предоставляет значения координат. Я не могу быть уверен, не увидев ваш код, но, глядя на исходники pyshp, я обнаружил класс _Array, который используется в нескольких местах.

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())

__Repr__ может объяснить, почему вы считаете, что видите стандартный список или кортеж, хотя на самом деле это пользовательский класс. Я собрал скрипту Python, которая демонстрирует исключение при предоставлении класса _Array pyshp для json.dumps().

Чтобы исправить эту проблему, вы должны передать координаты.tolist() к вашему вызову dumps.

json.dumps({"Points" : coordinates.tolist()}) 
Другие вопросы по тегам