使用for循环从列表中打印均匀分布的表 [英] Printing evenly spaced table from a list with a for-loop

查看:67
本文介绍了使用for循环从列表中打印均匀分布的表的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

很抱歉问这个非常基本的问题,但是我真的被困在这里...我尝试使用Google搜索,并使用搜索功能,但是找不到我要寻找的内容. /p>

我正在尝试从对象列表中打印值表.但是,由于名称"字符串的大小相差很大,因此它会使整个表倾斜,从而使其几乎不可读.我尝试在 \ t 之间添加制表符,但列仍未对齐.我可以在此打印语句中添加一些内容,以构成一个漂亮的直线表吗?

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

解决方案

您可以尝试执行以下操作:

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

I'm sorry for asking this really elementary question, but I'm really stuck here... I've tried googling this, and using the search function, but can't find what I'm looking for.

I'm trying to print a table of values from a list of objects. But as the "name" string varies a lot in size, it skews the whole table, making it almost unreadable. I've tried adding tabs inbetween with \t, but the columns are still disaligned. Is there something I can add to this print statement to make a nice, straight table?

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

解决方案

You can try something like this:

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

This finds the maximum length of the rows in your data and prints a table that is evenly spaced. In this case, max_lens uses zip to zip together all items in a given 'column' (think all items in the name column, for instance). Then, it finds the length of the longest string (as @Bakuriu points out, these need to be converted to strings in case any of the fields aren't strings) and stores that as the length of the 'column'. Then in the iteration, you specify a width which is going to be equal to the maximum length of that 'column', and pass in the value for that column on that row (hope that makes sense :) ).

The format method makes use of a the very powerful string formatting specification. This is a pretty basic example, but it can be modified to fit much more dynamic situations (such as those where you have numerous rows, etc.).

As for an example of how it could work with your data, you could try the below example. Note that this is not the most readable of code (which is important in Python), so if you were to do something similar, it may be worth it to actually write out some of the for loops so that it is a bit more obvious what is going on (since as I said, it is a bit obfuscated :) ):

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

这篇关于使用for循环从列表中打印均匀分布的表的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆