Printing Lists as Tabular Data
我对python还很陌生,现在我正努力将数据格式化为打印输出。
我有一个用于两个标题的列表,以及一个应该是表内容的矩阵。像这样:
1 2 3 4 | teams_list = ["Man Utd","Man City","T Hotspur"] data = np.array([[1, 2, 1], [0, 1, 0], [2, 4, 2]]) |
请注意,标题名称的长度不一定相同。但是,数据条目都是整数。
现在,我想用一种表格格式来表示这个,类似于:
1 2 3 4 | Man Utd Man City T Hotspur Man Utd 1 0 0 Man City 1 1 0 T Hotspur 0 1 2 |
我有一种预感,这一定有一个数据结构,但我找不到它。我试过使用字典和格式化打印,试过使用缩进的循环,试过用字符串打印。
我相信一定有一个非常简单的方法来做这件事,但我可能因为缺乏经验而错过了它。
为此,有一些轻量级和有用的python包:
1。表格:https://pypi.python.org/pypi/tableate
1 2 3 4 5 6 | >>> from tabulate import tabulate >>> print tabulate([['Alice', 24], ['Bob', 19]], headers=['Name', 'Age']) Name Age ------ ----- Alice 24 Bob 19 |
表格有许多选项可以指定标题和表格格式。
1 2 3 4 5 | >>> print tabulate([['Alice', 24], ['Bob', 19]], headers=['Name', 'Age'], tablefmt='orgtbl') | Name | Age | |--------+-------| | Alice | 24 | | Bob | 19 | |
2。prettytable:https://pypi.python.org/pypi/prettytable
1 2 3 4 5 6 7 8 9 10 11 | >>> from prettytable import PrettyTable >>> t = PrettyTable(['Name', 'Age']) >>> t.add_row(['Alice', 24]) >>> t.add_row(['Bob', 19]) >>> print t +-------+-----+ | Name | Age | +-------+-----+ | Alice | 24 | | Bob | 19 | +-------+-----+ |
prettytable有从csv、html、sql数据库读取数据的选项。此外,还可以选择数据子集、排序表和更改表样式。
三。文本表:https://pypi.python.org/pypi/texttable
1 2 3 4 5 6 7 8 9 10 11 | >>> from texttable import Texttable >>> t = Texttable() >>> t.add_rows([['Name', 'Age'], ['Alice', 24], ['Bob', 19]]) >>> print t.draw() +-------+-----+ | Name | Age | +=======+=====+ | Alice | 24 | +-------+-----+ | Bob | 19 | +-------+-----+ |
使用texttable,您可以控制水平/垂直对齐、边框样式和数据类型。
其他选项:
- TerminalTables很容易从字符串列表中绘制终端/控制台应用程序中的表。支持多行。
- ascii table ascii table可以通过内置的扩展阅读器类读取和写入各种各样的ascii表格式。
Python2.7的一些特殊代码:
1 2 3 4 | row_format ="{:>15}" * (len(teams_list) + 1) print row_format.format("", *teams_list) for team, row in zip(teams_list, data): print row_format.format(team, *row) |
这依赖于
1 2 3 4 5 6 | >>> import pandas >>> pandas.DataFrame(data, teams_list, teams_list) Man Utd Man City T Hotspur Man Utd 1 2 1 Man City 0 1 0 T Hotspur 2 4 2 |
实际上,python非常容易做到这一点。
类似的东西
1 2 | for i in range(10): print '%-12i%-12i' % (10 ** i, 20 ** i) |
将有输出
1 2 3 4 5 6 7 8 9 10 | 1 1 10 20 100 400 1000 8000 10000 160000 100000 3200000 1000000 64000000 10000000 1280000000 100000000 25600000000 1000000000 512000000000 |
字符串中的%本质上是一个转义字符,它后面的字符告诉python应该采用哪种格式的数据。字符串外部和之后的百分比告诉python您打算使用前一个字符串作为格式字符串,并且应将以下数据放入指定的格式。
在这种情况下,我使用"%-12i"两次。要分解每个部分:
1 2 3 | '-' (left align) '12' (how much space to be given to this part of the output) 'i' (we are printing an integer) |
来自文档:https://docs.python.org/2/library/stdtypes.html字符串格式
更新sven marnach在python 3.4中的工作答案:
1 2 3 4 | row_format ="{:>15}" * (len(teams_list) + 1) print(row_format.format("", *teams_list)) for team, row in zip(teams_list, data): print(row_format.format(team, *row)) |
当我这样做的时候,我想对如何格式化表的细节有一些控制。特别是,我希望标题单元格的格式与正文单元格的格式不同,并且表列宽只能与每个单元格所需的宽度相同。我的解决方案是:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | def format_matrix(header, matrix, top_format, left_format, cell_format, row_delim, col_delim): table = [[''] + header] + [[name] + row for name, row in zip(header, matrix)] table_format = [['{:^{}}'] + len(header) * [top_format]] \ + len(matrix) * [[left_format] + len(header) * [cell_format]] col_widths = [max( len(format.format(cell, 0)) for format, cell in zip(col_format, col)) for col_format, col in zip(zip(*table_format), zip(*table))] return row_delim.join( col_delim.join( format.format(cell, width) for format, cell, width in zip(row_format, row, col_widths)) for row_format, row in zip(table_format, table)) print format_matrix(['Man Utd', 'Man City', 'T Hotspur', 'Really Long Column'], [[1, 2, 1, -1], [0, 1, 0, 5], [2, 4, 2, 2], [0, 1, 0, 6]], '{:^{}}', '{:<{}}', '{:>{}.3f}', ' ', ' | ') |
输出结果如下:
1 2 3 4 5 | | Man Utd | Man City | T Hotspur | Really Long Column Man Utd | 1.000 | 2.000 | 1.000 | -1.000 Man City | 0.000 | 1.000 | 0.000 | 5.000 T Hotspur | 2.000 | 4.000 | 2.000 | 2.000 Really Long Column | 0.000 | 1.000 | 0.000 | 6.000 |
我想这就是你要找的。
这是一个简单的模块,它只计算表条目所需的最大宽度,然后使用rjust和ljust对数据进行漂亮的打印。
如果您希望左标题右对齐,只需更改此呼叫:
1 | print >> out, row[0].ljust(col_paddings[0] + 1), |
从第53行开始:
1 | print >> out, row[0].rjust(col_paddings[0] + 1), |
纯Python 3
1 2 3 4 5 6 7 8 9 10 11 12 | def print_table(data, cols, wide): '''Prints formatted data on columns of given width.''' n, r = divmod(len(data), cols) pat = '{{:{}}}'.format(wide) line = ' '.join(pat * cols for _ in range(n)) last_line = pat * r print(line.format(*data)) print(last_line.format(*data[n*cols:])) data = [str(i) for i in range(27)] print_table(data, 6, 12) |
将打印
1 2 3 4 5 | 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 |
我将尝试遍历列表,并使用csv格式化程序来表示您想要的数据。
可以指定制表符、逗号或任何其他字符作为分隔符。
否则,只需在列表中循环并在每个元素后打印" "
http://docs.python.org/library/csv.html网站
I found this just looking for a way to output simple columns. If you just need no-fuss columns, then you can use this:
1 2 3 | print("Titlex\tTitley\tTitlez") for x, y, z in data: print(x,"\t", y,"\t", z) |
编辑:我试图尽可能的简单,因此手工做了一些事情,而不是使用团队列表。要概括到OP的实际问题:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | #Column headers print("", end="\t") for team in teams_list: print("", team, end="") print() # rows for team, row in enumerate(data): teamlabel = teams_list[team] while len(teamlabel) < 9: teamlabel ="" + teamlabel print(teamlabel, end="\t") for entry in row: print(entry, end="\t") print() |
Ouputs:
1 2 3 4 | Man Utd Man City T Hotspur Man Utd 1 2 1 Man City 0 1 0 T Hotspur 2 4 2 |
但这似乎不再比其他答案简单了,也许它的好处是不需要更多的进口。但是@campkeith的答案已经达到了这一点,并且更加强大,因为它可以处理更广泛的标签长度。
一个简单的方法是循环所有列,测量它们的宽度,为最大宽度创建一个行模板,然后打印行。这并不完全是你想要的,因为在这种情况下,你首先必须把标题放在表格中,但我认为它可能对其他人有用。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | table = [ ["","Man Utd","Man City","T Hotspur"], ["Man Utd", 1, 0, 0], ["Man City", 1, 1, 0], ["T Hotspur", 0, 1, 2], ] def print_table(table): longest_cols = [ (max([len(str(row[i])) for row in table]) + 3) for i in range(len(table[0])) ] row_format ="".join(["{:>" + str(longest_col) + <p><center>[wp_ad_camp_3]</center></p><hr><P>下面的函数将使用python 3(也可能是python 2)创建请求的表(有或没有numpy)。我已经选择了设置每列的宽度以匹配最长的团队名称。如果您想为每一列使用团队名称的长度,可以修改它,但是会更复杂。</P><P>注意:对于python 2中的直接等价物,可以用itertools中的<wyn>izip</wyn>替换<wyn>zip</wyn>。</P>[cc lang="python"]def print_results_table(data, teams_list): str_l = max(len(t) for t in teams_list) print("".join(['{:>{length}s}'.format(t, length = str_l) for t in [""] + teams_list])) for t, row in zip(teams_list, data): print("".join(['{:>{length}s}'.format(str(x), length = str_l) for x in [t] + row])) teams_list = ["Man Utd","Man City","T Hotspur"] data = [[1, 2, 1], [0, 1, 0], [2, 4, 2]] print_results_table(data, teams_list) |
这将生成下表:
1 2 3 4 | Man Utd Man City T Hotspur Man Utd 1 2 1 Man City 0 1 0 T Hotspur 2 4 2 |
如果您想使用竖线分隔符,可以用
参考文献:
- 关于格式化的很多信息https://pyformat.info/(旧格式和新格式风格)
- 官方的python教程(相当好)-https://docs.python.org/3/tutorial/inputuput.html字符串格式方法
- 官方的python信息(很难阅读)https://docs.python.org/3/library/string.html字符串格式
- 其他资源-https://www.python-course.eu/python3_-formatted_output.php