0

pprint用来很好地打印 adict并且它工作正常。现在我切换到使用OrderedDictfrom 模块collections。不幸的是,pprint路由似乎没有认识到这些对象或多或少dict是 s 并且回退到将其打印为长线。

>>> d = { i:'*'*i for i in range(8) }
>>> pprint.pprint(d)
{0: '',
 1: '*',
 2: '**',
 3: '***',
 4: '****',
 5: '*****',
 6: '******',
 7: '*******'}
>>> pprint.pprint(collections.OrderedDict(d))
OrderedDict([(0, ''), (1, '*'), (2, '**'), (3, '***'), (4, '****'), (5, '*****'), (6, '******'), (7, '*******')])

有什么方法可以更好地表示OrderedDicts 吗?也许即使它们嵌套一个普通的dictlist

4

4 回答 4

3

我为此找到了一个相对简单的解决方案,但它包含使您的有序字典的输出看起来与常规dict对象完全一样的风险。

使用上下文管理器来防止pprint对字典键进行排序的原始解决方案来自这个答案

@contextlib.contextmanager
def pprint_OrderedDict():
    pp_orig = pprint._sorted
    od_orig = OrderedDict.__repr__
    try:
        pprint._sorted = lambda x:x
        OrderedDict.__repr__ = dict.__repr__
        yield
    finally:
        pprint._sorted = pp_orig
        OrderedDict.__repr__ = od_orig

(您也可以只使用 修补OrderedDict.__repr__方法dict.__repr__,但请不要。)

例子:

>>> foo = [('Roger', 'Owner'), ('Diane', 'Manager'), ('Bob', 'Manager'),
...        ('Ian', 'Associate'), ('Bill', 'Associate'), ('Melinda', 'Associate')]

>>> d = OrderedDict(foo)
>>> pprint.pprint(d)
OrderedDict([('Roger', 'Owner'), ('Diane', 'Manager'), ('Bob', 'Manager'), ('Ian', 'Associate'), ('Bill', 'Associate'), ('Melinda', 'Associate')])

>>> pprint.pprint(dict(d))
{'Bill': 'Associate',
 'Bob': 'Manager',
 'Diane': 'Manager',
 'Ian': 'Associate',
 'Melinda': 'Associate',
 'Roger': 'Owner'}

>>> with pprint_OrderedDict():
...     pprint.pprint(d)
...
{'Roger': 'Owner',
 'Diane': 'Manager',
 'Bob': 'Manager',
 'Ian': 'Associate',
 'Bill': 'Associate',
 'Melinda': 'Associate'}
于 2016-12-22T21:04:51.970 回答
2

试试这个:

d = collections.OrderedDict({ i:'*'*i for i in range(8) })

编辑

pprint.pprint(list(d.items()))

于 2014-01-29T01:23:33.790 回答
1

如果您专门针对 CPython* 3.6 或更高版本,则可以只使用常规字典而不是OrderedDict. 您会错过一些独有的方法OrderedDict,并且(还)不能保证可移植到其他 Python 实现,** 但它可能是完成您正在尝试做的事情的最简单方法。

* CPython 是 Python 的参考实现,可以从 python.org 下载。
** CPython从 PyPy 窃取了这个想法,所以你也可以依赖它在那里工作。

于 2016-12-22T22:07:22.070 回答
0

我意识到这是一种 necroposting,但我想我会发布我使用的内容。它的主要优点是它的 aoutput 可以读回 python,例如,允许在表示之间切换(例如,我在 JSON 文件中使用它)。当然,它通过从其内部 _format 函数中删除一些代码来破坏 pprint 封装。

#!/bin/env python
from __future__ import print_function

import pprint;
from collections import OrderedDict
import json
import sys


class MyPP (pprint.PrettyPrinter):
    def _format(self, object, stream, indent, allowance, context, level):
        if not isinstance(object, OrderedDict) :
            return pprint.PrettyPrinter._format(self, object, stream, indent, allowance, context, level)
        level = level + 1
        objid = id(object)
        if objid in context:
            stream.write(_recursion(object))
            self._recursive = True
            self._readable = False
            return
        write = stream.write
        _len=len
        rep = self._repr(object, context, level - 1)
        typ = type(object)
        sepLines = _len(rep) > (self._width - 1 - indent - allowance)

        if self._depth and level > self._depth:
            write(rep)
            return

        write('OrderedDict([\n%s'%(' '*(indent+1),))
        if self._indent_per_level > 1:
            write((self._indent_per_level - 1) * ' ')
        length = _len(object)
        #import pdb; pdb.set_trace()
        if length:
            context[objid] = 1
            indent = indent + self._indent_per_level
            items = object.items()
            key, ent = items[0]
            rep = self._repr(key, context, level)
            write('( ')
            write(rep)
            write(', ')
            self._format(ent, stream, indent + _len(rep) + 2,
                         allowance + 1, context, level)
            write(' )')
            if length > 1:
                for key, ent in items[1:]:
                    rep = self._repr(key, context, level)
                    if sepLines:
                        write(',\n%s( %s , ' % (' '*indent, rep))
                    else:
                        write(', ( %s , ' % rep)
                    self._format(ent, stream, indent + _len(rep) + 2,
                                 allowance + 1, context, level)
                    write(' )')

            indent = indent - self._indent_per_level
            del context[objid]
        write('])')
        return

pp = MyPP(indent=1)
handle=open(sys.argv[1],"r")
values=json.loads(handle.read(),object_pairs_hook=OrderedDict)
pp.pprint(values)
于 2017-10-03T11:28:14.497 回答