2014-02-18 66 views
12

我使用此代码打印出更漂亮一些dict成JSON:漂亮打印JSON转储

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

输出:

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

这是一个有点太多(换行符每个列表元素!)。

我应该使用哪种语法有...

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

呢?

+2

这不完全是您的问题的答案,但是如果您只是在寻找一种简单易用的数据格式眼睛,你可以试试YAML。对列表和字典等集合有两种语法,“块”(其中缩进显示嵌套)和“流”(括号用于执行该作业)。默认情况下,PyYAML的输出对不包含任何其他容器的列表和字典使用“流”语法,这听起来像你想要的漂亮打印。 – Blckknght

+0

谢谢@Blckknght。YAML是成熟的/稳定的/便携式的,并且可能在未来几年/未来版本的Python中可用?它会成为一个标准吗? (抱歉,所有这些问题;)) – Basj

+0

另一个评论:我想避免转换成字符串,因为当我'加载'我的JSON文件到'Dict',如果它是一个字符串,我没有访问了到'列表'(或者我需要解析字符串到列表中,但这是一个耻辱,必须这样做...) – Basj

回答

7

写自己的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) 

输出:

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

这真的很复杂吗?哇 – jpaugh

+0

从我所知道的。 –

+0

我期待大约10行。我猜[Haskell](http://haskell.org)让我宠坏了! – jpaugh

0

也许不是很有效,但是考虑一个简单的情况下(在Python 3有些测试,但可能会工作在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) 

这可能会给你一些想法,shor完全编写自己的序列化程序。我用我自己最喜欢的缩进技术,硬编码ensure_ascii,但你可以添加参数,并通过他们,或硬编码你自己的,等

2

另一种方法是print json.dumps(d, indent = None, separators=(',\n', ': '))

输出将是:

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

需要注意的是,虽然在https://docs.python.org/2.7/library/json.html#basic-usage官方文件说默认ARG游戏separators=None凹口 - 实际上是指“的separators=(', ',': ')使用默认值)。还要注意的是逗号分隔符不不是k/v对和列表区分元素。

+0

谢谢,但这并不完全是我们所需要的;我们希望拥有''[1,2,3]'在一行代替 – Basj

+0

对,它并不完美,但与其他怪物相比,它是精益和平均的;)如果我想变得有趣,我会使用https ://pypi.python.org/pypi/jq/ – MarkHu

+0

Tnx代表分隔符,帮助我支持lua的兼容性。在lua中,不允许有任何空间。 – josifoski

0

这已被窃听我一会还有,我发现了一个1个衬我几乎高兴:

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

,基本上所有列表或元组转换为字符串,然后使用与json.dumps缩进来格式化字典。那么你只需要删除引号和你的完成!

注意:无论dict如何嵌套,我都将字典转换为字符串以轻松转换所有列表/元组。

PS。我希望Python警察不会在我之后使用eval ...(小心使用)