在格式化初始JSON字符串而没有多余空格或换行符的情况下,将JSON字符串漂亮地打印为带有缩进的字符串的最简单方法是什么?
目前,我正在运行json.loads()
,然后在结果上运行json.dumps()
和indent=2
。这行得通,但感觉就像是我在花很多精力在计算上。
是否有更简单或更有效的(内置)方式来漂亮地打印JSON字符串? (同时将其保留为有效JSON)
示例
import requests
import json
response = requests.get('http://spam.eggs/breakfast')
one_line_json = response.content.decode('utf-8')
pretty_json = json.dumps(json.loads(response.content), indent=2)
print(f'Original: {one_line_json}')
print(f'Pretty: {pretty_json}')
输出:
Original: {"breakfast": ["spam", "spam", "eggs"]}
Pretty: {
"breakfast": [
"spam",
"spam",
"eggs"
]
}
答案 0 :(得分:3)
json.dumps(obj, indent=2)
比pprint
更好,因为:
pprint
不会。 pprint_vs_dumps.py
import cProfile
import json
import pprint
from urllib.request import urlopen
def custom_pretty_print():
url_to_read = "https://www.cbcmusic.ca/Component/Playlog/GetPlaylog?stationId=96&date=2018-11-05"
with urlopen(url_to_read) as resp:
pretty_json = json.dumps(json.load(resp), indent=2)
print(f'Pretty: {pretty_json}')
def pprint_json():
url_to_read = "https://www.cbcmusic.ca/Component/Playlog/GetPlaylog?stationId=96&date=2018-11-05"
with urlopen(url_to_read) as resp:
info = json.load(resp)
pprint.pprint(info)
cProfile.run('custom_pretty_print()')
>>> 71027 function calls (42309 primitive calls) in 0.084 seconds
cProfile.run('pprint_json()')
>>>164241 function calls (140121 primitive calls) in 0.208 seconds
感谢@tobias_k指出我的错误。
答案 1 :(得分:2)
我认为对于真正的JSON对象打印来说,它可能和它一样好。 timeit(number=10000)
花费了大约5.659214497s
:
import json
d = {
'breakfast': [
'spam', 'spam', 'eggs',
{
'another': 'level',
'nested': [
{'a':'b'},
{'c':'d'}
]
}
],
'foo': True,
'bar': None
}
s = json.dumps(d)
q = json.dumps(json.loads(s), indent=2)
print(q)
我尝试使用pprint
,但实际上它不会打印纯JSON字符串,除非将其转换为Python dict
,这会丢失您的true
,null
和false
等有效的JSON,如其他答案中所述。同样,它不会保留项目出现的顺序,因此,如果顺序对于可读性很重要,那就不好了。
只是为了好玩,我启动了以下功能:
def pretty_json_for_savages(j, indentor=' '):
ind_lvl = 0
temp = ''
for i, c in enumerate(j):
if c in '{[':
print(indentor*ind_lvl + temp.strip() + c)
ind_lvl += 1
temp = ''
elif c in '}]':
print(indentor*ind_lvl + temp.strip() + '\n' + indentor*(ind_lvl-1) + c, end='')
ind_lvl -= 1
temp = ''
elif c in ',':
print(indentor*(0 if j[i-1] in '{}[]' else ind_lvl) + temp.strip() + c)
temp = ''
else:
temp += c
print('')
# {
# "breakfast":[
# "spam",
# "spam",
# "eggs",
# {
# "another": "level",
# "nested":[
# {
# "a": "b"
# },
# {
# "c": "d"
# }
# ]
# }
# ],
# "foo": true,
# "bar": null
# }
它打印得还不错,毫不奇怪的是,花了16.701202023s
才能在timeit(number=10000)
中运行,这是json.dumps(json.loads())
的 3倍您。除非花费一些时间对其进行优化,否则构建自己的函数来实现此目标可能不值得,并且由于缺少builtin
,最好坚持使用枪支,因为您的努力很可能收益递减。