我正在使用pprint
来很好地打印dict
并且它正常工作。现在,我转而使用模块OrderedDict
中的collections
。不幸的是,pprint
路由似乎并没有意识到这些对象也或多或少dict
,并且回退到打印为长行。
>>> 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, '*******')])
是否可以更好地表达OrderedDict
s?也许即使它们嵌套 in 正常dict
或list
?
答案 0 :(得分:3)
我找到了一个相对简单的解决方案,但它包含了使您的有序字典的输出看起来像是常规dict
对象的风险。
使用上下文管理器阻止pprint
排序字典键的原始解决方案来自this answer。
@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'}
答案 1 :(得分:2)
试试这个:
d = collections.OrderedDict({ i:'*'*i for i in range(8) })
修改强>
pprint.pprint(list(d.items()))
答案 2 :(得分:1)
如果您专门针对CPython * 3.6或更高版本,那么您可以just use regular dictionaries代替OrderedDict
。你会错过几个methods exclusive to OrderedDict
,但这并不能保证可以移植到其他Python实现,**但它可能是完成你想要做的最简单的方法。
* CPython是Python的参考实现,可以从python.org下载 ** CPython stole this idea from PyPy,所以你可以依赖它在那里工作。
答案 3 :(得分:0)
我意识到这是一种恶作剧,但我认为我会发布我使用的内容。它的主要优点是它的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)