在Python中格式化JSON
当初始JSON字符串在没有额外空格或换行符的情况下格式化时,将JSON字符串打印为缩进字符串的最简单方法是什么 目前,我正在运行在Python中格式化JSON,python,json,python-3.x,Python,Json,Python 3.x,当初始JSON字符串在没有额外空格或换行符的情况下格式化时,将JSON字符串打印为缩进字符串的最简单方法是什么 目前,我正在运行json.loads(),然后在结果上运行json.dumps()和indent=2。这是可行的,但我觉得我把很多计算都浪费掉了 有没有一种更简单或更高效(内置)的方式来漂亮地打印JSON字符串?(同时将其保留为有效的JSON) 示例 import requests import json response = requests.get('http://spam.eg
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"
]
}
json.dumps(obj,indent=2)
优于pprint
,因为:
pprint
不会李>
pprint\u vs\u 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指出我的错误 json.dumps(obj,indent=2)
优于pprint
,因为:
pprint
不会李>
pprint\u vs\u 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指出我的错误 我认为对于一个真正的JSON对象打印,它可能是最好的
timeit(数字=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字符串,除非它转换为Pythondict
,这会丢失另一个答案中提到的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
# }
它的打印效果非常好,毫不奇怪,在
timeit(number=10000)
中运行时需要发出一声呜呜声16.701202023s
,这是json.dumps(json.loads())
的3倍。除非您花一些时间对其进行优化,否则构建您自己的函数来实现这一点可能是不值得的,而且由于缺少内置的,因此,您最好持之以恒,因为您的努力很可能会带来递减的回报。我认为对于真正的JSON对象打印,这可能是最好的了timeit(数字=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字符串,除非它转换为Pythondict
,这会丢失另一个答案中提到的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
# }
它的打印效果非常好,毫不奇怪,在timeit(number=10000)
中运行时需要发出一声呜呜声16.701202023s
,这是json.dumps(json.loads())
的3倍。为了实现这一点,构建自己的函数可能不值得,除非您花一些时间对其进行优化,并且缺少内置的,你最好还是持枪,因为你的努力很可能会带来递减的回报。你可能会用漂亮的print@SuperStew但是输出是一个格式化的Python对象,而不是JSON(例如,True
vsTrue
,None
vsnull
),然后格式化并打印,不管怎样。我不认为json.load
和json.dumps
比任何其他方法都要昂贵,例如使用pprint
而不是dumps
。可能更快。@Idlehands,然后OP调用Python对象上的json.dump
,将其转换为json。整个问题是关于JSON输出的。Python对象的字符串表示形式与JSON不同,尽管两者相似。@WhiteHotLoveTiger-您能为您试图解码的页面类型提供一个可测试的示例吗?链接“”未解析。如果您提供可用的URL,我可以更新我的答案以反映解码HTTP请求的成本print@SuperStew但是输出是一个格式化的Python对象,而不是JSON(例如,True
vsTrue
,None
vsnull
),然后格式化并打印,不管怎样。我不认为json.load
和json.dumps
比任何其他方法都要昂贵,例如使用pprint
而不是dumps
。可能更快。@Idlehands,然后OP调用Python对象上的json.dump
,将其转换为json。整个问题是关于JSON输出的。Python对象的字符串表示形式与JSON不同,尽管两者相似。@WhiteHotLoveTiger-您能为您试图解码的页面类型提供一个可测试的示例吗?链接“”未解析。如果您提供了可用的URL,我可以更新我的答案以反映解码HTTP请求的成本。但是这比使用json.dumps
快吗?我对此表示严重怀疑。而且,结果可能不是有效的JSON。啊,好问题,他确实指定了更“高效”的,不是吗。我可能错误地将其解释为更少的代码行。我必须通过配置文件来直接比较效率。代码行甚至不止一行,因为您只是用一个函数调用替换另一个函数调用。如果有的话,您不需要indent
参数,而是