Any way to properly pretty-print ordered dictionar

2020-02-02 04:21发布

I like the pprint module in Python. I use it a lot for testing and debugging. I frequently use the width option to make sure the output fits nicely within my terminal window.

It has worked fine until they added the new ordered dictionary type in Python 2.7 (another cool feature I really like). If I try to pretty-print an ordered dictionary, it doesn't show nicely. Instead of having each key-value pair on its own line, the whole thing shows up on one long line, which wraps many times and is hard to read.

Does anyone here have a way to make it print nicely, like the old unordered dictionaries? I could probably figure something out, possibly using the PrettyPrinter.format method, if I spend enough time, but I am wondering if anyone here already knows of a solution.

UPDATE: I filed a bug report for this. You can see it at http://bugs.python.org/issue10592.

14条回答
做自己的国王
2楼-- · 2020-02-02 04:58

You can also use this simplification of the kzh answer:

pprint(data.items(), indent=4)

It preserves the order and will output almost the same than the webwurst answer (print through json dump).

查看更多
混吃等死
3楼-- · 2020-02-02 04:59

The following will work if the order of your OrderedDict is an alpha sort, since pprint will sort a dict before print.

pprint(dict(o.items()))
查看更多
孤傲高冷的网名
4楼-- · 2020-02-02 05:01

As a temporary workaround you can try dumping in JSON format. You lose some type information, but it looks nice and keeps the order.

import json

pprint(data, indent=4)
# ^ugly

print(json.dumps(data, indent=4))
# ^nice
查看更多
我欲成王,谁敢阻挡
5楼-- · 2020-02-02 05:03

As of Python 3.8 : pprint.PrettyPrinter exposes the sort_dicts keyword parameter.

True by default, setting it to False will leave the dictionary unsorted.

>>> from pprint import PrettyPrinter

>>> x = {'John': 1,
>>>      'Mary': 2,
>>>      'Paul': 3,
>>>      'Lisa': 4,
>>>      }

>>> PrettyPrinter(sort_dicts=False).pprint(x)

Will output :

{'John': 1, 
 'Mary': 2, 
 'Paul': 3,
 'Lisa': 4}

Reference : https://docs.python.org/3/library/pprint.html

查看更多
【Aperson】
6楼-- · 2020-02-02 05:07

Here’s a way that hacks the implementation of pprint. pprint sorts the keys before printing, so to preserve order, we just have to make the keys sort in the way we want.

Note that this impacts the items() function. So you might want to preserve and restore the overridden functions after doing the 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'}
查看更多
做个烂人
7楼-- · 2020-02-02 05:07

The pprint() method is just invoking the __repr__() method of things in it, and OrderedDict doesn't appear to do much in it's method (or doesn't have one or something).

Here's a cheap solution that should work IF YOU DON'T CARE ABOUT THE ORDER BEING VISIBLE IN THE PPRINT OUTPUT, which may be a big if:

class PrintableOrderedDict(OrderedDict):
    def __repr__(self):
        return dict.__repr__(self)

I'm actually surprised that the order isn't preserved... ah well.

查看更多
登录 后发表回答