次のようなことを試すことができます:
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を指定し、その行のその列の値を渡します(意味があることを願っています:))。zip
name
width
この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