/ / Całkiem drukuj zrzuty JSON - json, serializacja, słownik, zrzut, python-2.x

Ładne zrzuty JSON - json, serializacja, słownik, zrzut, python-2.x

Używam tego kodu, aby całkiem wydrukować niektóre dict do JSON:

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

Wyjście:

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

To trochę zbyt wiele (nowa linia dla każdego elementu listy!).

Jakiej składni powinienem użyć, aby ...

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

zamiast ?

Odpowiedzi:

7 dla odpowiedzi № 1

Napisz własny serializator 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)

Wydajność:

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

2 dla odpowiedzi nr 2

Inną alternatywą jest print json.dumps(d, indent = None, separators=(",n", ": "))

Dane wyjściowe będą:

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

Zauważ, że chociaż oficjalne dokumenty w https://docs.python.org/2.7/library/json.html#basic-usage powiedzmy, że domyślne argumenty to separators=None - to właściwie oznacza "użyj domyślnego separators=(", ",": ") ). Zauważ również, że separator przecinka nie rozróżnia par k / v i elementów listy.


1 dla odpowiedzi nr 3

Skończyło się na użyciu jsbeautifier:

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

Wydajność:

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

0 dla odpowiedzi nr 4

Być może nie tak wydajne, ale rozważ prostszy przypadek (nieco przetestowany w Pythonie 3, ale prawdopodobnie działałby również w Pythonie 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 )

To może dać ci kilka pomysłów, z wyjątkiem pisaniacałkowicie własny serializator. Użyłem mojej własnej ulubionej techniki wcięć i zakodowałem na stałe sure_ascii, ale możesz dodać parametry i przekazać je dalej lub na stałe zakodować własne itp.


0 dla odpowiedzi № 5

Dręczyło mnie to również od jakiegoś czasu, znalazłem 1 liner, z którego jestem prawie zadowolony:

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

To zasadniczo konwertuje wszystkie listy lub krotki na łańcuch, a następnie używa json.dumps z wcięciem do sformatowania dyktowania. Następnie wystarczy usunąć cytaty i gotowe!

Uwaga: konwertuję dict na łańcuch, aby łatwo przekonwertować wszystkie listy / krotki, bez względu na to, jak zagnieżdżony jest dykt.

PS. Mam nadzieję, że policja Pythona nie będzie mnie ścigać za używanie eval ... (używaj ostrożnie)