我使用以下代码在Python中打印json:
json.dumps(json_output, indent=2, separators=(',', ': ')
这会打印我的json,如:
{
"rows_parsed": [
[
"a",
"b",
"c",
"d"
],
[
"e",
"f",
"g",
"i"
],
]
}
但是,我希望它打印如下:
{
"rows_parsed": [
["a","b","c","d"],
["e","f","g","i"],
]
}
如何将数组中的数组全部保存在一行上?
答案 0 :(得分:0)
这是一种进行最少修改的方法:
import json
from json import JSONEncoder
import re
class MarkedList:
_list = None
def __init__(self, l):
self._list = l
z = {
"rows_parsed": [
MarkedList([
"a",
"b",
"c",
"d"
]),
MarkedList([
"e",
"f",
"g",
"i"
]),
]
}
class CustomJSONEncoder(JSONEncoder):
def default(self, o):
if isinstance(o, MarkedList):
return "##<{}>##".format(o._list)
b = json.dumps(z, indent=2, separators=(',', ':'), cls=CustomJSONEncoder)
b = b.replace('"##<', "").replace('>##"', "")
print(b)
基本上,您要作为实例的格式要格式化的列表
MarkedList
,然后将它们解析为具有唯一唯一顺序的字符串
稍后从dumps
的输出中删除。这样做是为了消除放在json字符串周围的引号。
另一种更有效的方法,但更丑陋的方法是修补猴子
json.encoder._make_iterencode._iterencode
,内容类似:
def _iterencode(o, _current_indent_level):
if isinstance(o, str):
yield _encoder(o)
elif o is None:
yield 'null'
elif o is True:
yield 'true'
elif o is False:
yield 'false'
elif isinstance(o, int):
# see comment for int/float in _make_iterencode
yield _intstr(o)
elif isinstance(o, float):
# see comment for int/float in _make_iterencode
yield _floatstr(o)
elif isinstance(o, MarkedList):
yield _my_custom_parsing(o)
elif isinstance(o, (list, tuple)):
yield from _iterencode_list(o, _current_indent_level)
elif isinstance(o, dict):
yield from _iterencode_dict(o, _current_indent_level)
else:
if markers is not None:
markerid = id(o)
if markerid in markers:
raise ValueError("Circular reference detected")
markers[markerid] = o
o = _default(o)
yield from _iterencode(o, _current_indent_level)
if markers is not None:
del markers[markerid]
答案 1 :(得分:0)
我看不到如何在json.dumps中做到这一点。经过一番搜索,我遇到了一些选择: 一种选择是使用自定义函数进行一些后处理:
def fix_json_indent(text, indent=3):
space_indent = indent * 4
initial = " " * space_indent
json_output = []
current_level_elems = []
all_entries_at_level = None # holder for consecutive entries at exact space_indent level
for line in text.splitlines():
if line.startswith(initial):
if line[space_indent] == " ":
# line indented further than the level
if all_entries_at_level:
current_level_elems.append(all_entries_at_level)
all_entries_at_level = None
item = line.strip()
current_level_elems.append(item)
if item.endswith(","):
current_level_elems.append(" ")
elif current_level_elems:
# line on the same space_indent level
# no more sublevel_entries
current_level_elems.append(line.strip())
json_output.append("".join(current_level_elems))
current_level_elems = []
else:
# line at the exact space_indent level but no items indented further
if all_entries_at_level:
# last pending item was not the start of a new sublevel_entries.
json_output.append(all_entries_at_level)
all_entries_at_level = line.rstrip()
else:
if all_entries_at_level:
json_output.append(all_entries_at_level)
all_entries_at_level = None
if current_level_elems:
json_output.append("".join(current_level_elems))
json_output.append(line)
return "\n".join(json_output)
另一种可能是正则表达式,但是它很难看,取决于您发布的代码的结构:
def fix_json_indent(text):
import re
return re.sub('{"', '{\n"', re.sub('\[\[', '[\n[', re.sub('\]\]', ']\n]', re.sub('}', '\n}', text))))