如何用Python漂亮地打印ASCII表?

2024-05-17 01:21:14 发布

您现在位置:Python中文网/ 问答频道 /正文

我正在寻找一种方法来美化这样的打印表格:

=======================
| column 1 | column 2 |
=======================
| value1   | value2   |
| value3   | value4   |
=======================

我找到了asciitable库,但它不处理边框等。我不需要任何复杂的数据项格式,它们只是字符串。我需要它来自动调整列的大小。

是否存在其他库或方法,或者我需要花几分钟来编写自己的库或方法?


Tags: 方法字符串格式column表格边框数据项value1
3条回答

这里有一个快速而肮脏的小函数,我编写它来显示来自SQL查询的结果,我只能通过SOAP API来实现。它要求输入一个或多个namedtuples序列作为表行。如果只有一个记录,它会以不同的方式打印出来。

它对我来说很方便,可能是你的起点:

def pprinttable(rows):
  if len(rows) > 1:
    headers = rows[0]._fields
    lens = []
    for i in range(len(rows[0])):
      lens.append(len(max([x[i] for x in rows] + [headers[i]],key=lambda x:len(str(x)))))
    formats = []
    hformats = []
    for i in range(len(rows[0])):
      if isinstance(rows[0][i], int):
        formats.append("%%%dd" % lens[i])
      else:
        formats.append("%%-%ds" % lens[i])
      hformats.append("%%-%ds" % lens[i])
    pattern = " | ".join(formats)
    hpattern = " | ".join(hformats)
    separator = "-+-".join(['-' * n for n in lens])
    print hpattern % tuple(headers)
    print separator
    _u = lambda t: t.decode('UTF-8', 'replace') if isinstance(t, str) else t
    for line in rows:
        print pattern % tuple(_u(t) for t in line)
  elif len(rows) == 1:
    row = rows[0]
    hwidth = len(max(row._fields,key=lambda x: len(x)))
    for i in range(len(row)):
      print "%*s = %s" % (hwidth,row._fields[i],row[i])

样本输出:

pkid                                 | fkn                                  | npi
-------------------------------------+--------------------------------------+----
405fd665-0a2f-4f69-7320-be01201752ec | 8c9949b9-552e-e448-64e2-74292834c73e | 0
5b517507-2a42-ad2e-98dc-8c9ac6152afa | f972bee7-f5a4-8532-c4e5-2e82897b10f6 | 0
2f960dfc-b67a-26be-d1b3-9b105535e0a8 | ec3e1058-8840-c9f2-3b25-2488f8b3a8af | 1
c71b28a3-5299-7f4d-f27a-7ad8aeadafe0 | 72d25703-4735-310b-2e06-ff76af1e45ed | 0
3b0a5021-a52b-9ba0-1439-d5aafcf348e7 | d81bb78a-d984-e957-034d-87434acb4e97 | 1
96c36bb7-c4f4-2787-ada8-4aadc17d1123 | c171fe85-33e2-6481-0791-2922267e8777 | 1
95d0f85f-71da-bb9a-2d80-fe27f7c02fe2 | 226f964c-028d-d6de-bf6c-688d2908c5ae | 1
132aa774-42e5-3d3f-498b-50b44a89d401 | 44e31f89-d089-8afc-f4b1-ada051c01474 | 1
ff91641a-5802-be02-bece-79bca993fdbc | 33d8294a-053d-6ab4-94d4-890b47fcf70d | 1
f3196e15-5b61-e92d-e717-f00ed93fe8ae | 62fa4566-5ca2-4a36-f872-4d00f7abadcf | 1

示例

>>> from collections import namedtuple
>>> Row = namedtuple('Row',['first','second','third'])
>>> data = Row(1,2,3)
>>> data
Row(first=1, second=2, third=3)
>>> pprinttable([data])
 first = 1
second = 2
 third = 3
>>> pprinttable([data,data])
first | second | third
------+--------+------
    1 |      2 |     3
    1 |      2 |     3

出于某种原因,当我在google搜索中包含“docutils”时,我偶然发现了texttable,这似乎是我要找的东西。

我很久以前就读过这个问题,并且完成了我自己漂亮的表格打印机的编写:^{}

我的用例是:

  • 我大部分时间想要一条单行线
  • 这足够聪明为我找到最好的格式
  • 可以输出不同的纯文本格式

在您的示例中,grid可能是最相似的输出格式:

from tabulate import tabulate
print tabulate([["value1", "value2"], ["value3", "value4"]], ["column 1", "column 2"], tablefmt="grid")
+------------+------------+
| column 1   | column 2   |
+============+============+
| value1     | value2     |
+------------+------------+
| value3     | value4     |
+------------+------------+

其他支持的格式有plain(无行)、simple(Pandoc简单表)、pipe(类似于PHP Markdown Extra中的表)、orgtbl(类似于Emacs的org模式中的表)、rst(类似于structuredtext中的简单表)。gridorgtbl在Emacs中很容易编辑。

性能方面,tabulateasciitable稍慢,但比PrettyTabletexttable快得多。

p.S.我也非常喜欢对齐数字by a decimal column。因此,这是数字的默认对齐方式(如果有)(可重写)。

相关问题 更多 >