【问题标题】:Printing evenly spaced table from a list with a for-loop使用for循环从列表中打印均匀分布的表格
【发布时间】:2012-12-02 04:10:36
【问题描述】:

很抱歉问了这个非常基本的问题,但我真的被困在这里了……我试过用谷歌搜索这个,并使用搜索功能,但找不到我要找的东西。

我正在尝试从对象列表中打印值表。但是由于“名称”字符串的大小变化很大,它会使整个表格倾斜,使其几乎无法阅读。我尝试在 \t 之间添加标签,但列仍然不对齐。我可以在这个打印语句中添加什么东西来制作一个漂亮、直接的表格吗?

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

【问题讨论】:

    标签: python for-loop python-2.x spacing tabular


    【解决方案1】:

    你可以试试这样的:

    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 指出的那样,如果任何字段不是字符串,则需要将它们转换为字符串)并将其存储为“列”的长度。然后在迭代中,您指定一个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
    

    【讨论】:

    • 我喜欢key=lambda x: len(x) :)
    • @khachik:这很讽刺,对吧?我永远无法用表情符号来判断。因为您应该只是使用key=len
    • @TimPietzcker 哈哈,很好,完全错过了讽刺(更好的key)。明天我会调整第一件事(并删除该评论:))。
    • 感谢蒂姆,抱歉 @khachik 最初的光顾评论 - 我的讽刺传感器太糟糕了 :)
    • 使用key=(lambda x: len(str(x))) 会稍加改进,因为(例如)我不希望level 属性是字符串。
    【解决方案2】:
    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

    【讨论】:

      【解决方案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
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2011-11-30
        • 1970-01-01
        • 1970-01-01
        • 2011-02-20
        • 2015-02-24
        • 1970-01-01
        • 2021-10-08
        • 1970-01-01
        相关资源
        最近更新 更多