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

kdt*_*kdt 60 python ascii tabular

我正在寻找一个用于打印这样的表的Python库:

=======================
| column 1 | column 2 |
=======================
| value1   | value2   |
| value3   | value4   |
=======================
Run Code Online (Sandbox Code Playgroud)

我找到了asciitable,但它不做边框等.我不需要任何复杂的数据项格式,它们只是字符串.我确实需要它来自动调整列数.

这样的事情存在,还是我需要花几分钟时间写自己的?

sas*_*nin 47

我很久以前就读过这个问题,并为桌子写完了自己的漂亮打印机:tabulate.

我的用例是:

  • 我大部分时间都想要一个班轮
  • 这足够聪明,可以为我找到最好的格式
  • 并可以输出不同的纯文本格式

举个例子,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     |
+------------+------------+
Run Code Online (Sandbox Code Playgroud)

其他支持的格式是plain(无行),simple(Pandoc简单表),pipe(如PHP Markdown Extra中的表),(如Emacs'org orgtbl模式中的rst表),(如reStructuredText中的简单表).grid并且orgtbl可以在Emacs中轻松编辑.

性能方面,tabulate稍微慢一点asciitable,但比PrettyTable和更快texttable.

PS我也是用十进制列对齐数字忠实粉丝.因此,如果有任何(可覆盖的),这是数字的默认对齐方式.

  • 我刚好需要一个制表解决方案,很幸运找到了您的图书馆!就像魅力一样:D万一您在听,只想说**谢谢** :) (2认同)
  • 是的,我在听。谢谢你的客气话。得到积极的反馈真是太好了。 (2认同)

Mat*_*ttH 37

这是一个快速而肮脏的小函数,我编写的用于显示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])
Run Code Online (Sandbox Code Playgroud)

样本输出:

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


kdt*_*kdt 18

出于某种原因,当我在谷歌搜索中包含'docutils'时,我偶然发现了文本表,这似乎是我正在寻找的.

  • 好一个。缺乏自动列宽检测;使用:http://pastebin.com/SAsPJUxM (2认同)

Rob*_*l86 12

我也写了我自己的解决方案.我试着保持简单.

https://github.com/Robpol86/terminaltables

from terminaltables import AsciiTable
table_data = [
    ['Heading1', 'Heading2'],
    ['row1 column1', 'row1 column2'],
    ['row2 column1', 'row2 column2']
]
table = AsciiTable(table_data)
print table.table
+--------------+--------------+
| Heading1     | Heading2     |
+--------------+--------------+
| row1 column1 | row1 column2 |
| row2 column1 | row2 column2 |
+--------------+--------------+

table.inner_heading_row_border = False
print table.table
+--------------+--------------+
| Heading1     | Heading2     |
| row1 column1 | row1 column2 |
| row2 column1 | row2 column2 |
+--------------+--------------+

table.inner_row_border = True
table.justify_columns[1] = 'right'
table.table_data[1][1] += '\nnewline'
print table.table
+--------------+--------------+
| Heading1     |     Heading2 |
+--------------+--------------+
| row1 column1 | row1 column2 |
|              |      newline |
+--------------+--------------+
| row2 column1 | row2 column2 |
+--------------+--------------+
Run Code Online (Sandbox Code Playgroud)


Nic*_*mer 9

为此,我刚刚发布了术语表。例如,这

import termtables as tt

tt.print(
    [[1, 2, 3], [613.23236243236, 613.23236243236, 613.23236243236]],
    header=["a", "bb", "ccc"],
    style=tt.styles.ascii_thin_double,
    padding=(0, 1),
    alignment="lcr"
)
Run Code Online (Sandbox Code Playgroud)

得到你

+-----------------+-----------------+-----------------+
| a               |       bb        |             ccc |
+=================+=================+=================+
| 1               |        2        |               3 |
+-----------------+-----------------+-----------------+
| 613.23236243236 | 613.23236243236 | 613.23236243236 |
+-----------------+-----------------+-----------------+
Run Code Online (Sandbox Code Playgroud)

默认情况下,表格使用 Unicode框绘图字符呈现,

???????????????????????????????????????????????????????
? a               ?       bb        ?             ccc ?
???????????????????????????????????????????????????????
? 1               ?        2        ?               3 ?
???????????????????????????????????????????????????????
? 613.23236243236 ? 613.23236243236 ? 613.23236243236 ?
???????????????????????????????????????????????????????
Run Code Online (Sandbox Code Playgroud)

术语表是非常可配置的;查看测试以获取更多示例。


Pri*_*ngh 7

你可以试试BeautifulTable。它做你想做的事。这是它的文档中的一个示例

>>> from beautifultable import BeautifulTable
>>> table = BeautifulTable()
>>> table.columns.header = ["name", "rank", "gender"]
>>> table.rows.append(["Jacob", 1, "boy"])
>>> table.rows.append(["Isabella", 1, "girl"])
>>> table.rows.append(["Ethan", 2, "boy"])
>>> table.rows.append(["Sophia", 2, "girl"])
>>> table.rows.append(["Michael", 3, "boy"])
>>> print(table)
+----------+------+--------+
|   name   | rank | gender |
+----------+------+--------+
|  Jacob   |  1   |  boy   |
+----------+------+--------+
| Isabella |  1   |  girl  |
+----------+------+--------+
|  Ethan   |  2   |  boy   |
+----------+------+--------+
|  Sophia  |  2   |  girl  |
+----------+------+--------+
| Michael  |  3   |  boy   |
+----------+------+--------+
Run Code Online (Sandbox Code Playgroud)


Jan*_*sen 5

设计用于处理MattH版本的类型的使用w3m的版本接受:

import subprocess
import tempfile
import html
def pprinttable(rows):
    esc = lambda x: html.escape(str(x))
    sour = "<table border=1>"
    if len(rows) == 1:
        for i in range(len(rows[0]._fields)):
            sour += "<tr><th>%s<td>%s" % (esc(rows[0]._fields[i]), esc(rows[0][i]))
    else:
        sour += "<tr>" + "".join(["<th>%s" % esc(x) for x in rows[0]._fields])
        sour += "".join(["<tr>%s" % "".join(["<td>%s" % esc(y) for y in x]) for x in rows])
    with tempfile.NamedTemporaryFile(suffix=".html") as f:
        f.write(sour.encode("utf-8"))
        f.flush()
        print(
            subprocess
            .Popen(["w3m","-dump",f.name], stdout=subprocess.PIPE)
            .communicate()[0].decode("utf-8").strip()
        )

from collections import namedtuple
Row = namedtuple('Row',['first','second','third'])
data1 = Row(1,2,3)
data2 = Row(4,5,6)
pprinttable([data1])
pprinttable([data1,data2])
Run Code Online (Sandbox Code Playgroud)

结果是:

???????????
? first ?1?
???????????
?second ?2?
???????????
? third ?3?
???????????
?????????????????????
?first?second ?third?
?????????????????????
?1    ?2      ?3    ?
?????????????????????
?4    ?5      ?6    ?
?????????????????????
Run Code Online (Sandbox Code Playgroud)


dmo*_*odo 5

如果您想要一个具有列和行跨度的表,请尝试我的库dashtable

from dashtable import data2rst

table = [
        ["Header 1", "Header 2", "Header3", "Header 4"],
        ["row 1", "column 2", "column 3", "column 4"],
        ["row 2", "Cells span columns.", "", ""],
        ["row 3", "Cells\nspan rows.", "- Cells\n- contain\n- blocks", ""],
        ["row 4", "", "", ""]
    ]

# [Row, Column] pairs of merged cells
span0 = ([2, 1], [2, 2], [2, 3])
span1 = ([3, 1], [4, 1])
span2 = ([3, 3], [3, 2], [4, 2], [4, 3])

my_spans = [span0, span1, span2]

print(data2rst(table, spans=my_spans, use_headers=True))
Run Code Online (Sandbox Code Playgroud)

哪个输出:

+----------+------------+----------+----------+
| Header 1 | Header 2   | Header3  | Header 4 |
+==========+============+==========+==========+
| row 1    | column 2   | column 3 | column 4 |
+----------+------------+----------+----------+
| row 2    | Cells span columns.              |
+----------+----------------------------------+
| row 3    | Cells      | - Cells             |
+----------+ span rows. | - contain           |
| row 4    |            | - blocks            |
+----------+------------+---------------------+
Run Code Online (Sandbox Code Playgroud)