从带有for循环的列表中打印等距表

2024-05-17 14:43:24 发布

您现在位置:Python中文网/ 问答频道 /正文

我很抱歉问了这么简单的问题,但我真的被困在这里了。。。我试过用谷歌搜索这个,使用搜索功能,但找不到我要找的东西。

我正试图从对象列表中打印一个值表。但是由于“name”字符串的大小变化很大,它扭曲了整个表,使其几乎不可读。我已尝试在\t之间添加选项卡,但列仍不对齐。有什么东西我可以添加到这个打印声明,使一个漂亮,直表?

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

Tags: 对象字符串nameinself功能声明列表
3条回答

如果没有项的最大大小,因此无法使用格式说明符,则可以计算当前最大长度并使用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
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

你可以试试这样的方法:

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使用zip压缩给定“列”中的所有项(例如,考虑name列中的所有项)。然后,它找到最长字符串的长度(正如@Bakuriu指出的,如果任何字段不是字符串,这些字符串都需要转换为字符串),并将其存储为“column”的长度。然后在迭代中,指定一个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

相关问题 更多 >