반응형
json을 예쁘게 인쇄하지만 내부 어레이를 한 줄에 유지
이 코드를 사용하여 Python에서 json을 인쇄하고 있습니다.
json.dumps(json_output, indent=2, separators=(',', ': ')
그러면 다음과 같이 내 아들이 인쇄됩니다.
{
"rows_parsed": [
[
"a",
"b",
"c",
"d"
],
[
"e",
"f",
"g",
"i"
],
]
}
다만, 다음과 같이 인쇄해 주세요.
{
"rows_parsed": [
["a","b","c","d"],
["e","f","g","i"],
]
}
어레이에 있는 어레이를 위와 같이 모두 한 줄로 유지하려면 어떻게 해야 합니까?
다음은 가능한 한 적은 양의 수정으로 이를 수행하는 방법입니다.
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]
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)
다른 방법으로는 regex를 생각할 수 있지만 매우 보기 흉하고 게시한 코드의 구조에 따라 달라집니다.
def fix_json_indent(text):
import re
return re.sub('{"', '{\n"', re.sub('\[\[', '[\n[', re.sub('\]\]', ']\n]', re.sub('}', '\n}', text))))
언급URL : https://stackoverflow.com/questions/26264742/pretty-print-json-but-keep-inner-arrays-on-one-line-python
반응형
'source' 카테고리의 다른 글
(노드:3341) 폐지 경고: Mongoose: mpromise (0) | 2023.03.13 |
---|---|
React.cloneElement와 this.props.children은 언제 사용해야 합니까? (0) | 2023.03.13 |
설치된 Oracle Client가 32비트인지 64비트인지 확인하는 방법 (0) | 2023.03.13 |
React Native에서 버튼을 추가하는 방법 (0) | 2023.03.13 |
Strict 모드로 인해 My React 컴포넌트가 두 번 렌더링됩니다. (0) | 2023.03.13 |