将列表打印为表格数据

hjw*_*ide 314 python

我对Python很陌生,现在我正在努力为打印输出很好地格式化我的数据.

我有一个用于两个标题的列表,以及一个应该是表格内容的矩阵.像这样:

teams_list = ["Man Utd", "Man City", "T Hotspur"]
data = np.array([[1, 2, 1],
                 [0, 1, 0],
                 [2, 4, 2]])
Run Code Online (Sandbox Code Playgroud)

请注意,标题名称的长度不一定相同.但是,数据条目都是整数.

现在,我想以表格格式表示这个,如下所示:

            Man Utd   Man City   T Hotspur
  Man Utd         1          0           0
 Man City         1          1           0
T Hotspur         0          1           2
Run Code Online (Sandbox Code Playgroud)

我有预感,必须有一个数据结构,但我找不到它.我已经尝试使用字典和格式化打印,我已尝试使用缩进的for循环,我已尝试打印为字符串.

我确信必须有一个非常简单的方法来做到这一点,但由于缺乏经验,我可能会错过它.

ima*_*man 485

为此目的,有一些轻量级和有用的python包:

表格:https: //pypi.python.org/pypi/tabulate

from tabulate import tabulate
print(tabulate([['Alice', 24], ['Bob', 19]], headers=['Name', 'Age']))
Run Code Online (Sandbox Code Playgroud)

tabulate有许多选项来指定标题和表格格式.

Name      Age
------  -----
Alice      24
Bob        19
Run Code Online (Sandbox Code Playgroud)

2. PrettyTable:https://pypi.python.org/pypi/PrettyTable

print(tabulate([['Alice', 24], ['Bob', 19]], headers=['Name', 'Age'], tablefmt='orgtbl'))
Run Code Online (Sandbox Code Playgroud)

PrettyTable有从csv,html,sql数据库读取数据的选项.您还可以选择数据子集,排序表和更改表格样式.

3. texttable:https://pypi.python.org/pypi/texttable

| Name   |   Age |
|--------+-------|
| Alice  |    24 |
| Bob    |    19 |
Run Code Online (Sandbox Code Playgroud)

使用texttable,您可以控制水平/垂直对齐,边框样式和数据类型.

其他选择:

  • terminaltables从字符串列表列表中轻松绘制终端/控制台应用程序中的表.支持多行行.
  • asciitable Asciitable可以通过内置的Extension Reader Classes读写各种ASCII表格格式.

  • 我发现制表是一个非常有用的工具,用于构建以数据为中心的CLI工具.结合点击(点击安装点击),你就有了真正的炖菜. (9认同)
  • 这太好了,谢谢.就个人而言,在这三者中你更喜欢哪一个? (4认同)
  • 我只是使用了主要的程序包和IMO的“ beautifultable”(最佳,易于维护,良好的API和doco,支持彩色)。“文本表”-不错,保持良好的API,但是使用有色用法会使表不对齐。“ terminaltables”-很好,仅通过代码示例进行说明。“ PrettyTable”-好的,但是旧的表'titles'对我不起作用。“ Tabulate”-很好,但是在官方pypi版本中不支持列对齐`coalign`关键字。“表格”-一般,复杂的API,没有足够的常用用法示例。 (3认同)
  • terminaltable适合中文,也许是其他非英语语言 (2认同)

Sve*_*ach 171

Python 2.7的一些特殊代码:

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))
Run Code Online (Sandbox Code Playgroud)

这依赖于str.format()格式化规范的迷你语言.

  • 我比公认的解决方案更喜欢这个解决方案,因为它不需要第三方库。想要添加另一个方便的技巧:您可以使用字符串的最大长度作为列的宽度,而不是硬编码的数字。它将是这样的:f'{team:>{max_len_of_team}}'。 (7认同)
  • 如果正文中的数据大于标题,则可以根据第一行数据设置列宽。对于数据[0]中的t:row_format+="{:<"+str(len(t)+5)+"}" (5认同)
  • 如果使用python2.6,请记得在row_format上添加team_list索引:row_format ="{0:> 15} {1:> 15} {2:> 15}" (3认同)

jfs*_*jfs 71

>>> 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        
Run Code Online (Sandbox Code Playgroud)

  • @NielsBom:来输出格式化,留待数据分析和建模:) (61认同)
  • @JFSebastian对我来说更像是"来输出格式化,因为10分钟的numpy汇编让我的电脑听起来像吹风机而逃跑";-) (28认同)
  • 使用pandas仅用于输出格式化似乎是Overkill(资本O意图). (22认同)
  • 这看起来很有希望,谢谢,但我试图这样做,而不使用任何更多的导入库,而不是绝对必要的. (6认同)
  • @NielsBom:[`pip install numpy`现在在大多数平台上使用二进制轮子(没有编译)](https://pypi.python.org/pypi/numpy).显然,在此之前,其他二进制安装选项也可用. (4认同)

小智 55

Python实际上使这很容易.

就像是

for i in range(10):
    print '%-12i%-12i' % (10 ** i, 20 ** i)
Run Code Online (Sandbox Code Playgroud)

将有输出

1           1           
10          20          
100         400         
1000        8000        
10000       160000      
100000      3200000     
1000000     64000000    
10000000    1280000000  
100000000   25600000000
1000000000  512000000000
Run Code Online (Sandbox Code Playgroud)

字符串中的%本质上是一个转义字符,后面的字符告诉python数据应该具有什么样的格式.字符串外部和后面的%告诉python您打算使用前一个字符串作为格式字符串,并且应将以下数据放入指定的格式.

在这种情况下,我使用了"%-12i"两次.分解每个部分:

'-' (left align)
'12' (how much space to be given to this part of the output)
'i' (we are printing an integer)
Run Code Online (Sandbox Code Playgroud)

来自文档:https://docs.python.org/2/library/stdtypes.html#string-formatting

  • 这个答案让我走上了寻找我想要的东西的道路!对于 python 3,我最终像 `print('%-20.2f' %position['deg'], '%-17.2f'%position['v2'])` 一样使用它,其中 `.2` 指定精度浮点数“f” (2认同)
  • 也可以将其与 f 字符串语法结合起来动态地进行 algin:`f"<%-{max(a)}s>" % 1` (2认同)

Smr*_*ica 21

更新Sven Marnach在Python 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))
Run Code Online (Sandbox Code Playgroud)


Bea*_*der 19

我知道我参加聚会迟到了,但我刚刚为此创建了一个库,我认为这真的很有帮助。它非常简单,这就是为什么我认为你应该使用它。它被称为TableIT

基本用途

要使用它,请首先按照GitHub 页面上的下载说明进行操作。

然后导入:

import TableIt
Run Code Online (Sandbox Code Playgroud)

然后制作一个列表列表,其中每个内部列表都是一行:

table = [
    [4, 3, "Hi"],
    [2, 1, 808890312093],
    [5, "Hi", "Bye"]
]
Run Code Online (Sandbox Code Playgroud)

然后你所要做的就是打印它:

TableIt.printTable(table)
Run Code Online (Sandbox Code Playgroud)

这是你得到的输出:

+--------------------------------------------+
| 4            | 3            | Hi           |
| 2            | 1            | 808890312093 |
| 5            | Hi           | Bye          |
+--------------------------------------------+
Run Code Online (Sandbox Code Playgroud)

字段名称

如果您愿意,您可以使用字段名称(如果您不使用字段名称,则不必说 useFieldNames=False 因为它默认设置为该名称):

+--------------------------------------------+
| 4            | 3            | Hi           |
| 2            | 1            | 808890312093 |
| 5            | Hi           | Bye          |
+--------------------------------------------+
Run Code Online (Sandbox Code Playgroud)

从中你会得到:

+--------------------------------------------+
| 4            | 3            | Hi           |
+--------------+--------------+--------------+
| 2            | 1            | 808890312093 |
| 5            | Hi           | Bye          |
+--------------------------------------------+
Run Code Online (Sandbox Code Playgroud)

还有其他用途,例如您可以这样做:


TableIt.printTable(table, useFieldNames=True)
Run Code Online (Sandbox Code Playgroud)

从中:

+-----------------------------------------------+
| Name                  | Email                 |
+-----------------------+-----------------------+
| Richard               | richard@fakeemail.com |
| Tasha                 | tash@fakeemail.com    |
+-----------------------------------------------+
Run Code Online (Sandbox Code Playgroud)

或者你可以这样做:

+--------------------------------------------+
| 4            | 3            | Hi           |
+--------------+--------------+--------------+
| 2            | 1            | 808890312093 |
| 5            | Hi           | Bye          |
+--------------------------------------------+
Run Code Online (Sandbox Code Playgroud)

从中你得到:

+-----------------------+
|       | a     | b     |
+-------+-------+-------+
| x     | a + x | a + b |
| z     | a + z | z + b |
+-----------------------+
Run Code Online (Sandbox Code Playgroud)

颜色

您也可以使用颜色。

您可以通过使用 color 选项(默认设置为 None)并指定 RGB 值使用颜色。

使用上面的例子:

import TableIt

myList = [
    ["Name", "Email"],
    ["Richard", "richard@fakeemail.com"],
    ["Tasha", "tash@fakeemail.com"]
]

TableIt.print(myList, useFieldNames=True)
Run Code Online (Sandbox Code Playgroud)

然后你会得到:

在此处输入图片说明

请注意,打印颜色可能不适合您,但它的工作方式与其他打印彩色文本的库完全相同。我已经测试过,每种颜色都有效。蓝色也不会像使用默认的34mANSI 转义序列那样混乱(如果您不知道那是什么也没关系)。无论如何,这一切都来自这样一个事实,即每种颜色都是 RGB 值,而不是系统默认值。

更多信息

有关更多信息,请查看GitHub 页面

  • @Endle_Zhenbo,我知道已经有一段时间了,但我终于在该项目上放置了许可证。 (2认同)

Peg*_*sus 12

尝试丰富:https: //github.com/Textualize/rich

from rich.console import Console
from rich.table import Table

console = Console()

table = Table(show_header=True, header_style="bold magenta")
table.add_column("Date", style="dim", width=12)
table.add_column("Title")
table.add_column("Production Budget", justify="right")
table.add_column("Box Office", justify="right")
table.add_row(
    "Dec 20, 2019", "Star Wars: The Rise of Skywalker", "$275,000,000", "$375,126,118"
)
table.add_row(
    "May 25, 2018",
    "[red]Solo[/red]: A Star Wars Story",
    "$275,000,000",
    "$393,151,347",
)
table.add_row(
    "Dec 15, 2017",
    "Star Wars Ep. VIII: The Last Jedi",
    "$262,000,000",
    "[bold]$1,332,539,889[/bold]",
)

console.print(table)
Run Code Online (Sandbox Code Playgroud)

https://github.com/willmcgugan/rich/raw/master/imgs/table.png

在此输入图像描述


Emi*_*röm 10

一个简单的方法是遍历所有列,测量它们的宽度,为该最大宽度创建一个 row_template,然后打印行。这不完全是您要查找的内容,因为在这种情况下,您首先必须将标题放在表格中,但我认为它可能对其他人有用。

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) + "}" for longest_col in longest_cols])
    for row in table:
        print(row_format.format(*row))
Run Code Online (Sandbox Code Playgroud)

你像这样使用它:

>>> print_table(table)

            Man Utd   Man City   T Hotspur
  Man Utd         1          0           0
 Man City         1          1           0
T Hotspur         0          1           2
Run Code Online (Sandbox Code Playgroud)


cod*_*bae 10

table_data= [[1,2,3],[4,5,6],[7,8,9]]

for row in table_data:
    print("{: >20} {: >20} {: >20}".format(*row))
Run Code Online (Sandbox Code Playgroud)

输出:

               1                  2                3
               4                  5                6
               7                  8                9
Run Code Online (Sandbox Code Playgroud)

其中f字符串格式化

  1. ">" 用于右对齐
  2. “<”用于左对齐

20是可以根据需要改变的空间宽度。


小智 9

当我这样做时,我喜欢控制表的格式化细节.特别是,我希望标题单元格具有与正文单元格不同的格式,并且表格列宽度只能与每个单元格所需的格式一样宽.这是我的解决方案:

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}', '\n', ' | ')
Run Code Online (Sandbox Code Playgroud)

这是输出:

                   | 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
Run Code Online (Sandbox Code Playgroud)


Bog*_*dan 8

我想就是你要找的东西.

这是一个简单的模块,它只计算表条目所需的最大宽度,然后只使用rjustljust来完成数据的漂亮打印.

如果您希望左侧标题右对齐,只需更改此调用:

 print >> out, row[0].ljust(col_paddings[0] + 1),
Run Code Online (Sandbox Code Playgroud)

从第53行到:

 print >> out, row[0].rjust(col_paddings[0] + 1),
Run Code Online (Sandbox Code Playgroud)


Woj*_*ski 7

就用它

from beautifultable import BeautifulTable

table = BeautifulTable()
table.column_headers = ["", "Man Utd","Man City","T Hotspur"]
table.append_row(['Man Utd',  1,  2,  3])
table.append_row(['Man City', 7, 4,  1])
table.append_row(['T Hotspur', 3, 2,  2])
print(table)
Run Code Online (Sandbox Code Playgroud)

结果,您将得到如此整洁的桌子,仅此而已。 在此处输入图片说明

  • 此方法已弃用,请使用 [table.rows.append() 和 table.columns.header](https://pypi.org/project/beautifultable/) 代替 (3认同)

Dio*_*dea 6

以下函数将使用 Python 3(也可能是 Python 2)创建请求的表(带或不带 numpy)。我选择将每列的宽度设置为与最长的团队名称相匹配。如果你想在每列中使用团队名称的长度,你可以修改它,但会更复杂。

注意:对于 Python 2 中的直接等效项,您可以将 替换zipizipitertools 中的。

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)
Run Code Online (Sandbox Code Playgroud)

这将产生下表:

            Man Utd  Man City T Hotspur
  Man Utd         1         2         1
 Man City         0         1         0
T Hotspur         2         4         2
Run Code Online (Sandbox Code Playgroud)

如果您想要垂直线分隔符,可以替换" ".join" | ".join

参考:


Dmi*_*try 6

对于简单的情况,您可以使用现代字符串格式(简化的斯文答案):
\n f\'{column1_value:15} {column2_value}\'

\n
table = {\n    \'Amplitude\': [round(amplitude, 3), \'m\xc2\xb3/h\'],\n    \'MAE\': [round(mae, 2), \'m\xc2\xb3/h\'],\n    \'MAPE\': [round(mape, 2), \'%\'],\n}\n\nfor metric, value in table.items():\n    print(f\'{metric:14} : {value[0]:>6.3f} {value[1]}\')\n
Run Code Online (Sandbox Code Playgroud)\n

输出:

\n
Amplitude      :  1.438 m\xc2\xb3/h\nMAE            :  0.171 m\xc2\xb3/h\nMAPE           : 27.740 %\n
Run Code Online (Sandbox Code Playgroud)\n

来源:https ://docs.python.org/3/tutorial/inputoutput.html#formatted-string-literals

\n


The*_*ian 5

纯Python 3

def print_table(data, cols, wide):
    '''Prints formatted data on columns of given width.'''
    n, r = divmod(len(data), cols)
    pat = '{{:{}}}'.format(wide)
    line = '\n'.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)
Run Code Online (Sandbox Code Playgroud)

将打印

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
Run Code Online (Sandbox Code Playgroud)