3

この本当に初歩的な質問をして申し訳ありませんが、ここで立ち往生しています...これをグーグルで検索して検索機能を使用しようとしましたが、探しているものが見つかりません。

オブジェクトのリストから値のテーブルを印刷しようとしています。しかし、「名前」文字列はサイズが大きく異なるため、表全体がゆがみ、ほとんど判読できなくなります。\tの間にタブを追加しようとしましたが、列はまだずれています。この print ステートメントに追加して、きれいでまっすぐなテーブルを作成できるものはありますか?

print "name","level","value"
for i in self.items:
    print i.name, i.lvl, i.value
4

3 に答える 3

6

次のようなことを試すことができます:

In [1]: headers = ["name","level","value"]

In [2]: vals1 = ["Some long name", "a level", "a value"]

In [3]: vals2 = ["An even longer name", "another level", "another value"]

In [4]: max_lens = [len(str(max(i, key=lambda x: len(str(x))))) for i in zip(headers, vals1, vals2)]

In [5]: for row in (headers, vals1, vals2):
   ...:     print '|'.join('{0:{width}}'.format(x, width=y) for x, y in zip(row, max_lens))
   ...:
   ...:
name               |level        |value
Some long name     |a level      |a value
An even longer name|another level|another value

これにより、データ内の行の最大長が検出され、等間隔のテーブルが出力されます。この場合、特定の「列」内のすべてのアイテムを圧縮するためにmax_lens使用します (たとえば、列内のすべてのアイテムを考えてください)。次に、最長の文字列の長さを見つけ (@Bakuriu が指摘しているように、フィールドのいずれかが文字列でない場合はこれらを文字列に変換する必要があります)、それを「列」の長さとして保存します。次に、反復で、その「列」の最大長に等しくなるaを指定し、その行のその列の値を渡します(意味があることを願っています:))。zipnamewidth

このformatメソッドは、非常に強力な文字列フォーマット仕様を利用します。これは非常に基本的な例ですが、より動的な状況 (多数の行がある場合など) に合わせて変更できます。

データでどのように機能するかの例として、以下の例を試すことができます。これは最も読みやすいコードではないことに注意してください (これは Python では重要です)。そのため、同様のことを行う場合は、ループの一部を実際に書き出すことで、何が行われているのforかがもう少し明確になります。進行中(私が言ったように、それは少し難読化されています:)):

In [1]: class MyClass(object):
   ...:     def __init__(self, a, b, c):
   ...:         self.name = a
   ...:         self.level = b
   ...:         self.value = c
   ...:
   ...:

In [2]: headers = ['name', 'level', 'value']

In [3]: vals1 = MyClass('Some long name', 'a level', 10348)

In [4]: vals2 = MyClass('An even longer name', 'another level', 100008484)

In [5]: items = (vals1, vals2)

In [6]: item_lens = [[getattr(item, x) for x in headers] for item in items]

In [7]: max_lens = [len(str(max(i, key=lambda x: len(str(x))))) for i in zip(*[headers] + item_lens)]

In [8]: print '|'.join('{0:{width}}'.format(x, width=y) for x, y in zip(headers, max_lens))
name               |level        |value

In [9]: for i in items:
   ...:     print '|'.join('{0:{width}}'.format(x, width=y) for x, y in zip([getattr(i, x) for x in headers], max_lens))
   ...:
   ...:
Some long name     |a level      |10348
An even longer name|another level|100008484
于 2012-12-14T06:55:33.347 に答える
5
print "%20s %20s %20s" % ("name","level","value")
for i in self.items:
    print "%20s %20s %20s" % (i.name, i.lvl, i.value)

フォーマット指定子を追加します。http://docs.python.org/2/library/stdtypes.html#string-formatting-operations

于 2012-12-14T06:52:20.433 に答える
2

項目の最大サイズがなく、したがって書式指定子を使用できない場合は、現在の最大長を計算してstr.center(またはstr.rjust)を使用できます。

>>> from collections import namedtuple
>>> Record = namedtuple('Record', ['name', 'lvl', 'value'])
>>> items = [Record('a', 5, 1000), Record('aaaaaa', 15376576, 17.8), Record('aaaaaaaaaaaaaaaa', 7462, 1000)]
>>> max_name_length = len(max(items, key=(lambda x: len(x[0])))[0])
>>> max_lvl_length = len(str(max(items, key=(lambda x: len(str(x[1]))))[1]))
>>> max_value_length = len(str(max(items, key=(lambda x: len(str(x[2]))))[2]))
>>> for item in items:
...     print '%s %s %s' % (item.name.center(max_name_length),
...                         str(item.lvl).center(max_lvl_length),
...                         str(item.value).center(max_value_length))
... 
       a            5     1000
     aaaaaa      15376576 17.8
aaaaaaaaaaaaaaaa   7462   1000
于 2012-12-14T06:54:59.263 に答える