[英]Disabling sorting mechanism in pprint output
我有一个很大的字典,我正在打印它以使用 prettyprint 查看,但是我如何才能保持格式但在 pprint 中取消排序机制?
使用sort_dicts=False
:
pprint.pprint(data, sort_dicts=False)
您可以猴子修补pprint 模块。
import pprint
pprint.pprint({"def":2,"ghi":3,"abc":1,})
pprint._sorted = lambda x:x
# Or, for Python 3.7:
# pprint.sorted = lambda x, key=None: x
pprint.pprint({"def":2,"ghi":3, "abc":1})
由于第二个输出基本上是随机排序的,因此您的输出可能与我的不同:
{'abc': 1, 'def': 2, 'ghi': 3}
{'abc': 1, 'ghi': 3, 'def': 2}
import pprint import contextlib @contextlib.contextmanager def pprint_nosort(): # Note: the pprint implementation changed somewhere # between 2.7.12 and 3.7.0. This is the danger of # monkeypatching! try: # Old pprint orig,pprint._sorted = pprint._sorted, lambda x:x except AttributeError: # New pprint import builtins orig,pprint.sorted = None, lambda x, key=None:x try: yield finally: if orig: pprint._sorted = orig else: del pprint.sorted # For times when you don't want sorted output with pprint_nosort(): pprint.pprint({"def":2,"ghi":3, "abc":1}) # For times when you do want sorted output pprint.pprint({"def":2,"ghi":3, "abc":1})
从 Python 3.8 开始,您最终可以使用sort_dicts=False
禁用它。 请注意,字典从 Python 3.7 开始是插入排序的(实际上,甚至从 3.6 开始)。
import pprint
data = {'not': 'sorted', 'awesome': 'dict', 'z': 3, 'y': 2, 'x': 1}
pprint.pprint(data, sort_dicts=False)
# prints {'not': 'sorted', 'awesome': 'dict', 'z': 3, 'y': 2, 'x': 1}
或者,创建一个漂亮的打印机对象:
pp = pprint.PrettyPrinter(sort_dicts=False)
pp.pprint(data)
这不会影响集合(仍然是排序的),但是集合没有插入顺序保证。
而不是pprint.pprint
,为自己节省 4 个字符并使用pprint.pp
,它不会排序:
pprint.pp(object, *args, sort_dicts=False, **kwargs)
打印对象的格式化表示,后跟换行符。 如果sort_dicts为 false(默认值),字典将按插入顺序显示其键,否则将排序字典键。
args
和kwargs
将作为格式化参数传递给pprint()
。3.8 版中的新功能。
您可以继承PrettyPrinter
并从_pprint_dict
中删除sorted(object.items())
。
注意:此代码是 Python 3.5+
# unsorted_pprint.py
from pprint import PrettyPrinter, _builtin_scalars, _recursion
__all__ = [
'UnsortedPrettyPrinter',
'pprint2',
'pformat2',
]
class UnsortedPrettyPrinter(PrettyPrinter):
"""Pretty printer that retains original dict ordering
"""
def __init__(self, *args, **kwargs):
super().__init__()
self._dispatch = {
**self._dispatch,
dict.__repr__: self._pprint_dict,
}
@staticmethod
def _pprint_dict(self, object, stream, indent, allowance, context, level):
write = stream.write
write('{')
if self._indent_per_level > 1:
write((self._indent_per_level - 1) * ' ')
length = len(object)
if length:
items = object.items()
self._format_dict_items(items, stream, indent, allowance + 1,
context, level)
write('}')
def format(self, object, context, maxlevels, level):
"""Format object for a specific context, returning a string
and flags indicating whether the representation is 'readable'
and whether the object represents a recursive construct.
"""
return self._safe_repr(object, context, maxlevels, level)
def _safe_repr(self, object, context, maxlevels, level):
typ = type(object)
if typ in _builtin_scalars:
return repr(object), True, False
r = getattr(typ, "__repr__", None)
if issubclass(typ, dict) and r is dict.__repr__:
if not object:
return "{}", True, False
objid = id(object)
if maxlevels and level >= maxlevels:
return "{...}", False, objid in context
if objid in context:
return _recursion(object), False, True
context[objid] = 1
readable = True
recursive = False
components = []
append = components.append
level += 1
saferepr = self._safe_repr
items = object.items()
for k, v in items:
krepr, kreadable, krecur = saferepr(k, context, maxlevels, level)
vrepr, vreadable, vrecur = saferepr(v, context, maxlevels, level)
append("%s: %s" % (krepr, vrepr))
readable = readable and kreadable and vreadable
if krecur or vrecur:
recursive = True
del context[objid]
return "{%s}" % ", ".join(components), readable, recursive
if (issubclass(typ, list) and r is list.__repr__) or \
(issubclass(typ, tuple) and r is tuple.__repr__):
if issubclass(typ, list):
if not object:
return "[]", True, False
format = "[%s]"
elif len(object) == 1:
format = "(%s,)"
else:
if not object:
return "()", True, False
format = "(%s)"
objid = id(object)
if maxlevels and level >= maxlevels:
return format % "...", False, objid in context
if objid in context:
return _recursion(object), False, True
context[objid] = 1
readable = True
recursive = False
components = []
append = components.append
level += 1
for o in object:
orepr, oreadable, orecur = self._safe_repr(o, context, maxlevels, level)
append(orepr)
if not oreadable:
readable = False
if orecur:
recursive = True
del context[objid]
return format % ", ".join(components), readable, recursive
rep = repr(object)
return rep, (rep and not rep.startswith('<')), False
def pprint2(object, stream=None, indent=1, width=80, depth=None, *,
compact=False):
"""Pretty-print a Python object to a stream [default is sys.stdout].
dict items are left unsorted.
"""
printer = UnsortedPrettyPrinter(
stream=stream,
indent=indent,
width=width,
depth=depth,
compact=compact,
)
printer.pprint(object)
def pformat2(object, indent=1, width=80, depth=None, *, compact=False):
"""Format a Python object into a pretty-printed representation.
dict items are left unsorted.
"""
return UnsortedPrettyPrinter(
indent=indent,
width=width,
depth=depth,
compact=compact,
).pformat(object)
我知道我在这里有点晚了,但我更喜欢禁用排序字典的方法是使用partial
:
from functools import partial
from pprint import pprint
pprint = partial(pprint, sort_dicts=False)
我个人喜欢这种方式,因为它引入了最小的差异。
它具有猴子修补的好处,因为您只需在一个地方进行更改(与其他选项不同),而不必弄乱pprint
的内部结构。
我正在使用 py3.8 但这应该在添加sort_dicts
选项时起作用。
您可以将json.dumps
与indent=4
一起使用。 这将创建一个格式化的字符串,可以很好地打印并且默认情况下不会对键进行排序。
注意:这也适用于旧蟒蛇
import json
d = {3:4, 1:2, 5:6}
print(json.dumps(d, indent=4))
output:
{
"3": 4,
"1": 2,
"5": 6
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.