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

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

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

注意,标题名称的长度不一定相同。但是,数据项都是整数。

现在,我想用表格的形式来表示,就像这样:

            Man Utd   Man City   T Hotspur
  Man Utd         1          0           0
 Man City         1          1           0
T Hotspur         0          1           2

我有一种预感,这一定有一个数据结构,但我找不到它。我尝试过使用字典和格式化打印,我尝试过使用缩进的for循环,我尝试过打印字符串。

我相信一定有一个非常简单的方法来做到这一点,但我可能因为缺乏经验而错过了它。


当前回答

有一些简单而有用的python包用于此目的:

1. 汇总:https://pypi.python.org/pypi/tabulate

from tabulate import tabulate
print(tabulate([['Alice', 24], ['Bob', 19]], headers=['Name', 'Age']))
Name      Age
------  -----
Alice      24
Bob        19

Tabulate有许多选项来指定标题和表格格式。

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

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数据库读取数据。你也可以选择子集的数据,排序表和改变表的样式。

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

from texttable import Texttable
t = Texttable()
t.add_rows([['Name', 'Age'], ['Alice', 24], ['Bob', 19]])
print(t.draw())
+-------+-----+
| Name  | Age |
+=======+=====+
| Alice | 24  |
+-------+-----+
| Bob   | 19  |
+-------+-----+

通过文本表,你可以控制水平/垂直对齐,边框样式和数据类型。

4. termtables: https://github.com/nschloe/termtables

import termtables as tt

string = tt.to_string(
    [["Alice", 24], ["Bob", 19]],
    header=["Name", "Age"],
    style=tt.styles.ascii_thin_double,
    # alignment="ll",
    # padding=(0, 1),
)
print(string)
+-------+-----+
| Name  | Age |
+=======+=====+
| Alice | 24  |
+-------+-----+
| Bob   | 19  |
+-------+-----+

通过文本表,你可以控制水平/垂直对齐,边框样式和数据类型。

其他选项:

在终端/控制台应用程序中,很容易从字符串的列表中绘制表格。支持多行。 asciitable可以通过内置的扩展阅读器类读取和写入广泛的ASCII表格式。

其他回答

将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))

我发现这只是为了寻找一种输出简单列的方法。如果你只是需要简单的列,那么你可以使用这个:

print("Titlex\tTitley\tTitlez")
for x, y, z in data:
    print(x, "\t", y, "\t", z)

编辑:我试图尽可能简单,因此手动做了一些事情,而不是使用团队列表。概括一下OP的实际问题:

#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:

          Man Utd  Man City  T Hotspur
  Man Utd       1       2       1   
 Man City       0       1       0   
T Hotspur       2       4       2   

但这似乎不再比其他答案简单,好处可能是它不需要更多的进口。但是@campkeith的答案已经满足了这一点,并且更加健壮,因为它可以处理更广泛的标签长度。

我觉得这就是你要找的东西。

这是一个简单的模块,它只是计算表项所需的最大宽度,然后使用rjust和ljust来打印数据。

如果你想让你的左标题右对齐,只需改变这个调用:

 print >> out, row[0].ljust(col_paddings[0] + 1),

从第53行开始

 print >> out, row[0].rjust(col_paddings[0] + 1),

我会尝试遍历列表,并使用CSV格式化器来表示所需的数据。

您可以指定制表符、逗号或任何其他字符作为分隔符。

否则,只需遍历列表并在每个元素后打印“\t”

http://docs.python.org/library/csv.html

Pure 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)

将打印

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