저는 파이썬의 pprint 모듈을 좋아합니다. 테스트와 디버깅을 위해 많이 사용합니다. 출력이 터미널 창에 잘 맞는지 확인하기 위해 너비 옵션을 자주 사용합니다.
Python 2.7 (내가 정말 좋아하는 또 다른 멋진 기능)에 새로운 정렬 된 사전 유형 을 추가 할 때까지 제대로 작동했습니다 . 정렬 된 사전을 예쁘게 인쇄하려고하면 제대로 표시되지 않습니다. 각 키-값 쌍을 고유 한 줄에 두는 대신 전체 내용이 한 줄에 표시되어 여러 번 줄 바꿈되어 읽기가 어렵습니다.
여기에있는 사람 중에 순서가 지정되지 않은 오래된 사전처럼 멋지게 인쇄 할 수있는 방법이 있습니까? 충분한 시간을 보내면 PrettyPrinter.format 메서드를 사용하여 뭔가 알아낼 수 있지만 여기에있는 누군가가 이미 해결책을 알고 있는지 궁금합니다.
업데이트 : 나는 이것에 대한 버그 보고서를 제출했습니다. http://bugs.python.org/issue10592 에서 볼 수 있습니다 .
답변
임시 해결 방법으로 JSON 형식으로 덤프를 시도 할 수 있습니다. 일부 유형 정보를 잃어 버렸지 만 멋지게 보이고 순서를 유지합니다.
import json
pprint(data, indent=4)
# ^ugly
print(json.dumps(data, indent=4))
# ^nice
답변
다음은 OrderedDict의 순서가 알파 정렬 인 경우 작동합니다. pprint는 인쇄 전에 사전을 정렬하기 때문입니다.
pprint(dict(o.items()))
답변
pprint()
내부적으로 stock 함수를 재정의하고 사용하여 작동하는 또 다른 답변이 있습니다 . 달리 내 일 이전 이 됩니다 핸들 OrderedDict
‘등으로 다른 컨테이너의 내부에요 list
또한 주어진 선택적인 키워드 인자를 처리 할 수 있어야합니다 – 그러나 그것은 다른 하나는 여유있는 출력 제어의 동일한 학위를 소지하지 않습니다.
stock 함수의 출력을 임시 버퍼로 리디렉션 한 다음 출력 스트림으로 보내기 전에 워드 랩핑합니다. 생성 된 최종 결과물은 예외적으로 예쁘지는 않지만 괜찮으며 해결 방법으로 사용하기에 “충분”할 수 있습니다.
2.0 업데이트
표준 라이브러리 textwrap
모듈 을 사용하여 단순화되고 Python 2 및 3에서 모두 작동하도록 수정되었습니다.
from collections import OrderedDict
try:
from cStringIO import StringIO
except ImportError: # Python 3
from io import StringIO
from pprint import pprint as pp_pprint
import sys
import textwrap
def pprint(object, **kwrds):
try:
width = kwrds['width']
except KeyError: # unlimited, use stock function
pp_pprint(object, **kwrds)
return
buffer = StringIO()
stream = kwrds.get('stream', sys.stdout)
kwrds.update({'stream': buffer})
pp_pprint(object, **kwrds)
words = buffer.getvalue().split()
buffer.close()
# word wrap output onto multiple lines <= width characters
try:
print >> stream, textwrap.fill(' '.join(words), width=width)
except TypeError: # Python 3
print(textwrap.fill(' '.join(words), width=width), file=stream)
d = dict((('john',1), ('paul',2), ('mary',3)))
od = OrderedDict((('john',1), ('paul',2), ('mary',3)))
lod = [OrderedDict((('john',1), ('paul',2), ('mary',3))),
OrderedDict((('moe',1), ('curly',2), ('larry',3))),
OrderedDict((('weapons',1), ('mass',2), ('destruction',3)))]
샘플 출력 :
pprint(d, width=40)
» {'john': 1, 'mary': 3, 'paul': 2}
pprint(od, width=40)
» OrderedDict([('john', 1), ('paul', 2),
('mary', 3)])
pprint(lod, width=40)
» [OrderedDict([('john', 1), ('paul', 2),
('mary', 3)]), OrderedDict([('moe', 1),
('curly', 2), ('larry', 3)]),
OrderedDict([('weapons', 1), ('mass',
2), ('destruction', 3)])]
답변
정렬 된 사전을 인쇄하려면
from collections import OrderedDict
d=OrderedDict([
('a', OrderedDict([
('a1',1),
('a2','sss')
])),
('b', OrderedDict([
('b1', OrderedDict([
('bb1',1),
('bb2',4.5)])),
('b2',4.5)
])),
])
나는한다
def dict_or_OrdDict_to_formatted_str(OD, mode='dict', s="", indent=' '*4, level=0):
def is_number(s):
try:
float(s)
return True
except ValueError:
return False
def fstr(s):
return s if is_number(s) else '"%s"'%s
if mode != 'dict':
kv_tpl = '("%s", %s)'
ST = 'OrderedDict([\n'; END = '])'
else:
kv_tpl = '"%s": %s'
ST = '{\n'; END = '}'
for i,k in enumerate(OD.keys()):
if type(OD[k]) in [dict, OrderedDict]:
level += 1
s += (level-1)*indent+kv_tpl%(k,ST+dict_or_OrdDict_to_formatted_str(OD[k], mode=mode, indent=indent, level=level)+(level-1)*indent+END)
level -= 1
else:
s += level*indent+kv_tpl%(k,fstr(OD[k]))
if i!=len(OD)-1:
s += ","
s += "\n"
return s
print dict_or_OrdDict_to_formatted_str(d)
어느 양보
"a": {
"a1": 1,
"a2": "sss"
},
"b": {
"b1": {
"bb1": 1,
"bb2": 4.5
},
"b2": 4.5
}
또는
print dict_or_OrdDict_to_formatted_str(d, mode='OD')
어느 양보
("a", OrderedDict([
("a1", 1),
("a2", "sss")
])),
("b", OrderedDict([
("b1", OrderedDict([
("bb1", 1),
("bb2", 4.5)
])),
("b2", 4.5)
]))
답변
.NET Framework 구현을 해킹하는 방법은 다음과 같습니다 pprint
.
pprint
인쇄하기 전에 키를 정렬하므로 순서를 유지하려면 원하는 방식으로 키를 정렬하면됩니다.
이는 items()
기능에 영향을 미칩니다 . 따라서 pprint를 수행 한 후 재정의 된 함수를 보존하고 복원 할 수 있습니다.
from collections import OrderedDict
import pprint
class ItemKey(object):
def __init__(self, name, position):
self.name = name
self.position = position
def __cmp__(self, b):
assert isinstance(b, ItemKey)
return cmp(self.position, b.position)
def __repr__(self):
return repr(self.name)
OrderedDict.items = lambda self: [
(ItemKey(name, i), value)
for i, (name, value) in enumerate(self.iteritems())]
OrderedDict.__repr__ = dict.__repr__
a = OrderedDict()
a[4] = '4'
a[1] = '1'
a[2] = '2'
print pprint.pformat(a) # {4: '4', 1: '1', 2: '2'}
답변
OrderedDict를 예쁜 인쇄하는 방법은 다음과 같습니다.
from collections import OrderedDict
import json
d = OrderedDict()
d['duck'] = 'alive'
d['parrot'] = 'dead'
d['penguin'] = 'exploded'
d['Falcon'] = 'discharged'
print(d)
print(json.dumps(d,indent=4))
OutPut:
OrderedDict([('duck', 'alive'), ('parrot', 'dead'), ('penguin', 'exploded'), ('Falcon', 'discharged')])
{
"duck": "alive",
"parrot": "dead",
"penguin": "exploded",
"Falcon": "discharged"
}
정렬 된 순서대로 키로 사전을 예쁘게 인쇄하고 싶다면
print(json.dumps(indent=4,sort_keys=True))
{
"Falcon": "discharged",
"duck": "alive",
"parrot": "dead",
"penguin": "exploded"
}
답변
이것은 매우 조잡하지만 임의의 Mappings 및 Iterables로 구성된 데이터 구조를 시각화하는 방법이 필요했고 이것이 포기하기 전에 생각해 낸 것입니다. 재귀 적이므로 중첩 된 구조와 목록을 통과합니다. 컬렉션의 Mapping 및 Iterable 추상 기본 클래스를 사용하여 거의 모든 것을 처리했습니다.
나는 간결한 파이썬 코드로 출력과 같은 거의 yaml을 목표로했지만 제대로 만들지 못했습니다.
def format_structure(d, level=0):
x = ""
if isinstance(d, Mapping):
lenk = max(map(lambda x: len(str(x)), d.keys()))
for k, v in d.items():
key_text = "\n" + " "*level + " "*(lenk - len(str(k))) + str(k)
x += key_text + ": " + format_structure(v, level=level+lenk)
elif isinstance(d, Iterable) and not isinstance(d, basestring):
for e in d:
x += "\n" + " "*level + "- " + format_structure(e, level=level+4)
else:
x = str(d)
return x
OrderedDict 및 OrderedDict 목록을 사용하는 일부 테스트 데이터 … (sheesh Python에는 OrderedDict 리터럴이 너무 많이 필요합니다 …)
d = OrderedDict([("main",
OrderedDict([("window",
OrderedDict([("size", [500, 500]),
("position", [100, 900])])),
("splash_enabled", True),
("theme", "Dark")])),
("updates",
OrderedDict([("automatic", True),
("servers",
[OrderedDict([("url", "http://server1.com"),
("name", "Stable")]),
OrderedDict([("url", "http://server2.com"),
("name", "Beta")]),
OrderedDict([("url", "http://server3.com"),
("name", "Dev")])]),
("prompt_restart", True)])),
("logging",
OrderedDict([("enabled", True),
("rotate", True)]))])
print format_structure(d)
다음 출력을 생성합니다.
main:
window:
size:
- 500
- 500
position:
- 100
- 900
splash_enabled: True
theme: Dark
updates:
automatic: True
servers:
-
url: http://server1.com
name: Stable
-
url: http://server2.com
name: Beta
-
url: http://server3.com
name: Dev
prompt_restart: True
logging:
enabled: True
rotate: True
더 나은 정렬을 위해 str.format ()을 사용하는 방법에 대해 약간의 생각이 있었지만 파고 들고 싶지는 않았습니다. 원하는 정렬 유형에 따라 필드 너비를 동적으로 지정해야하므로 까다 롭거나 번거로울 수 있습니다.
어쨌든, 이것은 읽을 수있는 계층 적 방식으로 데이터를 보여 주므로 저에게 효과적입니다!