Pythonのpprintモジュールが好きです。テストとデバッグによく使用します。幅オプションを頻繁に使用して、出力が端末ウィンドウにうまく収まるようにします。
新しい 順序付けられた辞書の種類 in Python 2.7(私が本当に気に入っている別のクールな機能)を追加するまでは問題なく動作しました。各キーと値のペアを独自の行に配置する代わりに、全体が1つの長い行に表示されるため、何度も折り返されて読みにくくなります。
古い順序付けられていない辞書のように、ここに誰かがそれをうまく印刷する方法がありますか?おそらく十分な時間を費やせば、おそらくPrettyPrinter.formatメソッドを使用して何かを見つけることができますが、ここの誰かがすでに解決策を知っているのではないかと思っています。
UPDATE:これに関するバグレポートを提出しました。 http://bugs.python.org/issue10592 で確認できます。
一時的な回避策として、JSON形式でダンプを試すことができます。一部のタイプ情報は失われますが、見栄えがよく、順序は変わりません。
import json
pprint(data, indent=4)
# ^ugly
print(json.dumps(data, indent=4))
# ^Nice
Pprintは印刷前に辞書をソートするため、OrderedDictの順序がアルファソートの場合、以下が機能します。
pprint(dict(o.items()))
ストックpprint()
関数を内部でオーバーライドして使用することで機能する別の答えがあります。私の 以前のものとは異なり 、それはwillOrderedDict
などの別のコンテナ内のlist
を処理し、またできるはずです与えられたオプションのキーワード引数を処理します—しかし、他のものが提供するのと同じ程度の出力を制御することはできません。
ストック関数の出力を一時バッファーにリダイレクトすることで動作し、Wordはそれを出力ストリームに送信する前にラップします。生成される最終出力は例外的にきれいではありませんが、それはまともであり、回避策として使用するのに「十分」である可能性があります。
Update 2.0
標準ライブラリtextwrap
モジュールを使用して簡素化され、Python 2&3。
_from collections import OrderedDict
try:
from cStringIO import StringIO
except ImportError: # Python 3
from io import StringIO
from pprint import pprint as pp_pprint
import sys
import textwrap
def pprint(object, **kwrds):
try:
width = kwrds['width']
except KeyError: # unlimited, use stock function
pp_pprint(object, **kwrds)
return
buffer = StringIO()
stream = kwrds.get('stream', sys.stdout)
kwrds.update({'stream': buffer})
pp_pprint(object, **kwrds)
words = buffer.getvalue().split()
buffer.close()
# Word wrap output onto multiple lines <= width characters
try:
print >> stream, textwrap.fill(' '.join(words), width=width)
except TypeError: # Python 3
print(textwrap.fill(' '.join(words), width=width), file=stream)
d = dict((('john',1), ('paul',2), ('mary',3)))
od = OrderedDict((('john',1), ('paul',2), ('mary',3)))
lod = [OrderedDict((('john',1), ('paul',2), ('mary',3))),
OrderedDict((('moe',1), ('curly',2), ('larry',3))),
OrderedDict((('weapons',1), ('mass',2), ('destruction',3)))]
_
サンプル出力:
_pprint(d, width=40)
_
"_{'john': 1, 'mary': 3, 'paul': 2}
_
_pprint(od, width=40)
_
" OrderedDict([('john', 1), ('paul', 2),
_('mary', 3)])
_
_pprint(lod, width=40)
_
" [OrderedDict([('john', 1), ('paul', 2),
_('mary', 3)]), OrderedDict([('moe', 1),
_
_('curly', 2), ('larry', 3)]),
_OrderedDict([('weapons', 1), ('mass',
2), ('destruction', 3)])]
順序付けられた辞書を印刷するには、例えば.
from collections import OrderedDict
d=OrderedDict([
('a', OrderedDict([
('a1',1),
('a2','sss')
])),
('b', OrderedDict([
('b1', OrderedDict([
('bb1',1),
('bb2',4.5)])),
('b2',4.5)
])),
])
私がやります
def dict_or_OrdDict_to_formatted_str(OD, mode='dict', s="", indent=' '*4, level=0):
def is_number(s):
try:
float(s)
return True
except ValueError:
return False
def fstr(s):
return s if is_number(s) else '"%s"'%s
if mode != 'dict':
kv_tpl = '("%s", %s)'
ST = 'OrderedDict([\n'; END = '])'
else:
kv_tpl = '"%s": %s'
ST = '{\n'; END = '}'
for i,k in enumerate(OD.keys()):
if type(OD[k]) in [dict, OrderedDict]:
level += 1
s += (level-1)*indent+kv_tpl%(k,ST+dict_or_OrdDict_to_formatted_str(OD[k], mode=mode, indent=indent, level=level)+(level-1)*indent+END)
level -= 1
else:
s += level*indent+kv_tpl%(k,fstr(OD[k]))
if i!=len(OD)-1:
s += ","
s += "\n"
return s
print dict_or_OrdDict_to_formatted_str(d)
どちらが得られますか
"a": {
"a1": 1,
"a2": "sss"
},
"b": {
"b1": {
"bb1": 1,
"bb2": 4.5
},
"b2": 4.5
}
または
print dict_or_OrdDict_to_formatted_str(d, mode='OD')
をもたらす
("a", OrderedDict([
("a1", 1),
("a2", "sss")
])),
("b", OrderedDict([
("b1", OrderedDict([
("bb1", 1),
("bb2", 4.5)
])),
("b2", 4.5)
]))
pprint
の実装をハッキングする方法を次に示します。 pprint
は印刷前にキーをソートするため、順序を保持するには、キーを希望の方法でソートする必要があります。
これはitems()
関数に影響することに注意してください。そのため、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'}
def pprint_od(od):
print "{"
for key in od:
print "%s:%s,\n" % (key, od[key]) # Fixed syntax
print "}"
そこに行きます^^
for item in li:
pprint_od(item)
または
(pprint_od(item) for item in li)
これはかなり粗雑ですが、任意のマッピングとイテラブルで構成されたデータ構造を視覚化する方法が必要であり、これはあきらめる前に思いついたものです。再帰的であるため、ネストされた構造とリストをうまく処理できます。コレクションのMappingおよびIterable抽象基本クラスを使用して、ほぼすべてを処理しました。
私は簡潔なpythonコードでほぼyamlのような出力を目指していましたが、うまくいきませんでした。
def format_structure(d, level=0):
x = ""
if isinstance(d, Mapping):
lenk = max(map(lambda x: len(str(x)), d.keys()))
for k, v in d.items():
key_text = "\n" + " "*level + " "*(lenk - len(str(k))) + str(k)
x += key_text + ": " + format_structure(v, level=level+lenk)
Elif isinstance(d, Iterable) and not isinstance(d, basestring):
for e in d:
x += "\n" + " "*level + "- " + format_structure(e, level=level+4)
else:
x = str(d)
return x
そして、OrderedDictとOrderedDictsのリストを使用したいくつかのテストデータ...(sheesh Python OrderedDictリテラルがひどく必要です...)
d = OrderedDict([("main",
OrderedDict([("window",
OrderedDict([("size", [500, 500]),
("position", [100, 900])])),
("splash_enabled", True),
("theme", "Dark")])),
("updates",
OrderedDict([("automatic", True),
("servers",
[OrderedDict([("url", "http://server1.com"),
("name", "Stable")]),
OrderedDict([("url", "http://server2.com"),
("name", "Beta")]),
OrderedDict([("url", "http://server3.com"),
("name", "Dev")])]),
("Prompt_restart", True)])),
("logging",
OrderedDict([("enabled", True),
("rotate", True)]))])
print format_structure(d)
次の出力が生成されます。
main:
window:
size:
- 500
- 500
position:
- 100
- 900
splash_enabled: True
theme: Dark
updates:
automatic: True
servers:
-
url: http://server1.com
name: Stable
-
url: http://server2.com
name: Beta
-
url: http://server3.com
name: Dev
Prompt_restart: True
logging:
enabled: True
rotate: True
Str.format()を使用して位置合わせを改善する方法についていくつかの考えがありましたが、それを掘り下げたくはありませんでした。必要な配置のタイプに応じて、フィールド幅を動的に指定する必要があります。これは、面倒または面倒になります。
とにかく、これは私のデータを読み取り可能な階層形式で表示するので、私にとってはうまくいきます!
私はこの不格好なモンキーパッチベースのハックをpython3.5でテストしましたが、動作します:
pprint.PrettyPrinter._dispatch[pprint._collections.OrderedDict.__repr__] = pprint.PrettyPrinter._pprint_dict
def unsorted_pprint(data):
def fake_sort(*args, **kwargs):
return args[0]
orig_sorted = __builtins__.sorted
try:
__builtins__.sorted = fake_sort
pprint.pprint(data)
finally:
__builtins__.sorted = orig_sorted
pprint
に通常の辞書ベースの要約を使用させ、呼び出し中はソートを無効にして、印刷用にキーが実際にソートされないようにします。
pprint()
メソッドは、その中の__repr__()
メソッドを呼び出しているだけであり、OrderedDict
はそのメソッドであまり処理を行っていないようです(または、何か)。
動作するはずの安価なソリューションを次に示しますPPRINT出力で注文が表示されない場合、これは次の場合に大きな可能性があります:
class PrintableOrderedDict(OrderedDict):
def __repr__(self):
return dict.__repr__(self)
実際、注文が保存されていないことに驚いています。
辞書項目がすべて1つのタイプである場合、驚くべきデータ処理ライブラリpandas
を使用できます。
>>> import pandas as pd
>>> x = {'foo':1, 'bar':2}
>>> pd.Series(x)
bar 2
foo 1
dtype: int64
または
>>> import pandas as pd
>>> x = {'foo':'bar', 'baz':'bam'}
>>> pd.Series(x)
baz bam
foo bar
dtype: object
pprint()
を再定義し、OrderedDict
の呼び出しをインターセプトできます。以下に簡単な図を示します。書かれているように、OrderedDict
オーバーライドコードは、渡された可能性のあるオプションのstream
、indent
、width
、またはdepth
キーワードを無視します。それらを実装するために拡張することができます。残念ながら、この手法は、list
of OrderDict
'sなどの別のコンテナ内でそれらを処理しません。
from collections import OrderedDict
from pprint import pprint as pp_pprint
def pprint(obj, *args, **kwrds):
if not isinstance(obj, OrderedDict):
# use stock function
return pp_pprint(obj, *args, **kwrds)
else:
# very simple sample custom implementation...
print "{"
for key in obj:
print " %r:%r" % (key, obj[key])
print "}"
l = [10, 2, 4]
d = dict((('john',1), ('paul',2), ('mary',3)))
od = OrderedDict((('john',1), ('paul',2), ('mary',3)))
pprint(l, width=4)
# [10,
# 2,
# 4]
pprint(d)
# {'john': 1, 'mary': 3, 'paul': 2}
pprint(od)
# {
# 'john':1
# 'paul':2
# 'mary':3
# }
ここにOrderedDictをきれいに印刷するための私のアプローチがあります
from collections import OrderedDict
import json
d = OrderedDict()
d['duck'] = 'alive'
d['parrot'] = 'dead'
d['penguin'] = 'exploded'
d['Falcon'] = 'discharged'
print d
print json.dumps(d,indent=4)
OutPut:
OrderedDict([('duck', 'alive'), ('parrot', 'dead'), ('penguin', 'exploded'), ('Falcon', 'discharged')])
{
"duck": "alive",
"parrot": "dead",
"penguin": "exploded",
"Falcon": "discharged"
}
ソートされた順序でキーを持つ辞書をきれいに印刷したい場合
print json.dumps(indent=4,sort_keys=True)
{
"Falcon": "discharged",
"duck": "alive",
"parrot": "dead",
"penguin": "exploded"
}