Disabling sorting mechanism in pprint output
Python 3.8 or newer:
Use sort_dicts=False
:
pprint.pprint(data, sort_dicts=False)
Python 3.7 or older:
You can monkey patch the pprint module.
import pprintpprint.pprint({"def":2,"ghi":3,"abc":1,})pprint._sorted = lambda x:x# Or, for Python 3.7:# pprint.sorted = lambda x, key=None: xpprint.pprint({"def":2,"ghi":3, "abc":1})
Since the 2nd output is essentiallly randomly sorted, your output may be different from mine:
{'abc': 1, 'def': 2, 'ghi': 3}{'abc': 1, 'ghi': 3, 'def': 2}
Another version that is more complex, but easier to use:
import pprintimport contextlib@contextlib.contextmanagerdef 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 outputwith pprint_nosort(): pprint.pprint({"def":2,"ghi":3, "abc":1})# For times when you do want sorted outputpprint.pprint({"def":2,"ghi":3, "abc":1})
As of Python 3.8, you can finally disable this using sort_dicts=False
. Note that dictionaries are insertion-ordered since Python 3.7 (and in practice, even since 3.6).
import pprintdata = {'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}
Alternatively, create a pretty printer object:
pp = pprint.PrettyPrinter(sort_dicts=False)pp.pprint(data)
This does not affect sets (which are still sorted), but then sets do not have insertion-ordering guarantees.
You can subclass PrettyPrinter
and remove the sorted(object.items())
from _pprint_dict
.
NOTE: this code is Python 3.5+
# unsorted_pprint.pyfrom 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('<')), Falsedef 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)