Bonitos estampados JSON volcados

Utilizo este código para imprimir bastante un dict en JSON:

 import json d = {'a': 'blah', 'b': 'foo', 'c': [1,2,3]} print json.dumps(d, indent = 2, separators=(',', ': ')) 

Salida:

 { "a": "blah", "c": [ 1, 2, 3 ], "b": "foo" } 

Esto es un poco demasiado (¡nueva línea para cada elemento de la lista!).

¿Qué syntax debo usar para tener esto?

 { "a": "blah", "c": [1, 2, 3], "b": "foo" } 

¿en lugar?

Escribe tu propio serializador JSON:

 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())) + "]" else: raise TypeError("Unknown type '%s' for json serialization" % str(type(o))) return ret inputJson = {'a': 'blah', 'b': 'foo', 'c': [1,2,3]} print to_json(inputJson) 

Salida:

 { "a": "blah", "c": [1,2,3], "b": "foo" } 

Otra alternativa es print json.dumps(d, indent = None, separators=(',\n', ': '))

La salida será:

 {"a": "blah", "c": [1, 2, 3], "b": "foo"} 

Tenga en cuenta que aunque los documentos oficiales en https://docs.python.org/2.7/library/json.html#basic-usage dicen que los argumentos predeterminados son separators=None – que en realidad significa “use default of separators=(', ',': ') ). Tenga en cuenta también que el separador de coma no distingue entre pares k / v y elementos de lista.

Terminé usando jsbeautifier :

 import jsbeautifier opts = jsbeautifier.default_options() opts.indent_size = 2 jsbeautifier.beautify(json.dumps(d), opts) 

Salida:

 { "a": "blah", "c": [1, 2, 3], "b": "foo" } 

Quizás no sea tan eficiente, pero considere un caso más simple (algo probado en Python 3, pero probablemente también funcionaría en Python 2):

 def dictJSONdumps( obj, levels, indentlevels = 0 ): import json if isinstance( obj, dict ): res = [] for ix in sorted( obj, key=lambda x: str( x )): temp = ' ' * indentlevels + json.dumps( ix, ensure_ascii=False ) + ': ' if levels: temp += dictJSONdumps( obj[ ix ], levels-1, indentlevels+1 ) else: temp += json.dumps( obj[ ix ], ensure_ascii=False ) res.append( temp ) return '{\n' + ',\n'.join( res ) + '\n}' else: return json.dumps( obj, ensure_ascii=False ) 

Esto podría darle algunas ideas, además de escribir su propio serializador por completo. Utilicé mi propia técnica de sangría favorita y asegurar_ascii con código fijo, pero podría agregar parámetros y pasarlos, o codificarlos por su cuenta, etc.

Esto también me ha estado molestando por un tiempo, encontré un forro 1 con el que estoy casi feliz:

 print json.dumps(eval(str(d).replace('[', '"[').replace(']', ']"').replace('(', '"(').replace(')', ')"')), indent=2).replace('\"\\"[', '[').replace(']\\"\"', ']').replace('\"\\"(', '(').replace(')\\"\"', ')') 

Eso esencialmente convierte todas las listas o tuplas en una cadena, luego usa json.dumps con sangría para formatear el dict. ¡Entonces solo necesitas quitar las comillas y listo!

Nota: Convierto el dictado en una cadena para convertir fácilmente todas las listas / tuplas sin importar cuán nested esté el dict.

PD. Espero que la Policía de Python no venga por mí por usar eval … (usar con cuidado)