Вопрос по json, python – JSON массива Python

11

У меня есть большой словарь, в котором есть большие массивы данных:

d = {'something': {'else': 'x'}, 'longnumbers': [1,2,3,4,54,6,67,7,7,8,8,8,6,4,3,3,5,6,7,4,3,5,6,54]}

Настоящий словарь имеет гораздо больше ключей и вложенную структуру. Когда я используюjson.dump безindentЯ получаю компактный однострочный вывод, который не читается. Когда я установилindent, он ставит новые строки после каждого разделителя, включая массивы.

Числовые массивы длинные и в итоге выглядят так:

  "longnumbers": [
    1, 
    2, 
    3, 
    4, 
    54, 
    6, 
    67, 
    7, 
    7, 
    8, 
    8, 
    8, 
    6, 
    4, 
    3, 
    3, 
    5, 
    6, 
    7, 
    4, 
    3, 
    5, 
    6, 
    54
  ], 

Есть ли способ получить красиво напечатанный JSON с уровнем отступа, но без размещения новых строк после элементов массива? В приведенном выше примере мне бы хотелось что-то вроде этого:

{
  "longnumbers": [1, 2, 3, 4, 54, 6, 67, 7, 7, 8, 8, 8, 6, 4, 3, 3, 5, 6, 7, 4, 3, 5, 6, 54],
  "something": {
    "else": "x"
  }
}
Вот чего я боялся jterrace
Скорее всего, вам придется кодировать это самостоятельно. Niklas B.
@NiklasB. К такому выводу я пришел, когда у меня возникла похожая проблема. К счастью,json Библиотека реализована на Python и не особенно сложна для чтения, что обеспечивает хорошую базу для вещей. Karl Knechtel
Я думаю, что хороший способ будет просто обернутьjson.dumps и только переопределить поведение для обработки диктов, проходя через все другие типы элементов. Niklas B.

Ваш Ответ

2   ответа
2

действительно должен быть вариант для указания разных отступов для двух разных типов контейнеров JSON. Альтернативный подход, если вы хотите оставаться совместимым с ядром Python JSON lib, это переопределить функцию (_make_iterencode() в настоящее время) в этой библиотеке, которая отвечает за обработкуindent.

Была трещина вповторная реализация _make_iterencode (), Только пришлось изменить нескольколинии сделатьindent вариант, при желании взять кортеж(hash-indent, array-indent), Но, к сожалению, придется заменить весь_make_iterencode() который оказывается довольно большим и плохо разложенным. Во всяком случае, следующие работы для 3.4-3.6:

import sys
import json

dat = {"b": [1, 2, 3, 4, 5, 6, 7, 8, 9, 10], "a": 1, "c": "x"}
indent = 2
print(json.dumps(dat, indent=indent))

if sys.version_info.major == 3 and 4 <= sys.version_info.minor <= 6:
  import _make_iterencode
  json.encoder._make_iterencode = _make_iterencode._make_iterencode
  indent = (2, None)

print(json.dumps(dat, indent=indent))

Gives:

{
  "c": "x",
  "a": 1,
  "b": [
    1,
    2,
    3,
    4,
    5,
    6,
    7,
    8,
    9,
    10
  ]
}
{
  "c": "x",
  "a": 1,
  "b": [1,2,3,4,5,6,7,8,9,10]
}
9

import numpy

INDENT = 3
SPACE = " "
NEWLINE = "\n"

def to_json(o, level=0):
    ret = ""
    if isinstance(o, dict):
        ret += "{" + NEWLINE
        comma = ""
        for k,v in o.iteritems():
            ret += comma
            comma = ",\n"
            ret += SPACE * INDENT * (level+1)
            ret += '"' + str(k) + '":' + SPACE
            ret += to_json(v, level + 1)

        ret += NEWLINE + SPACE * INDENT * level + "}"
    elif isinstance(o, basestring):
        ret += '"' + o + '"'
    elif isinstance(o, list):
        ret += "[" + ",".join([to_json(e, level+1) for e in o]) + "]"
    elif isinstance(o, bool):
        ret += "true" if o else "false"
    elif isinstance(o, int):
        ret += str(o)
    elif isinstance(o, float):
        ret += '%.7g' % o
    elif isinstance(o, numpy.ndarray) and numpy.issubdtype(o.dtype, numpy.integer):
        ret += "[" + ','.join(map(str, o.flatten().tolist())) + "]"
    elif isinstance(o, numpy.ndarray) and numpy.issubdtype(o.dtype, numpy.inexact):
        ret += "[" + ','.join(map(lambda x: '%.7g' % x, o.flatten().tolist())) + "]"
    elif o is None:
        ret += 'null'
    else:
        raise TypeError("Unknown type '%s' for json serialization" % str(type(o)))
    return ret
Этот ответ спас мой день!
Эта функция бесплатна для использования под лицензией BSD. jterrace

Похожие вопросы