Disabling sorting mechanism in pprint output Disabling sorting mechanism in pprint output python python

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)