如何在控制台中向已打印的表中添加新行?

Posted

技术标签:

【中文标题】如何在控制台中向已打印的表中添加新行?【英文标题】:How to add new rows to already printed table in console? 【发布时间】:2017-09-08 12:23:45 【问题描述】:

我的脚本需要在处理一些数字时打印一个表格。它的总运行时间是几个小时,我需要它在运行时向打印表添加越来越多的行。我正在尝试使用 PrettyTable,但我愿意接受其他建议如何完成它。这是我正在尝试做的一个示例:

from prettytable import PrettyTable
t = PrettyTable(['Name', 'Age'])
t.add_row(['Alice', 24])
print t

#do some work

t.add_row(['Bob', 19])
print t

我得到的结果是这样的:

+-------+-----+
|  Name | Age |
+-------+-----+
| Alice |  24 |
+-------+-----+
+-------+-----+
|  Name | Age |
+-------+-----+
| Alice |  24 |
|  Bob  |  19 |
+-------+-----+

有没有办法在每次添加一行时不打印整个表格,而只在已打印的内容下方打印一个新行?我想得到这样的东西:

+-------+-----+
|  Name | Age |
+-------+-----+
| Alice |  24 |
+-------+-----+
| Bob   |  19 |
+-------+-----+

第一列的左对齐将是一个不错的奖励。

【问题讨论】:

【参考方案1】:

如果您在列名定义中指定了足够的空格以涵盖所有传入项目的最大宽度,则下面的代码将涵盖您所要求的所有内容(感谢此问题的所有贡献者 - 我已经使用了这里提出的所有内容在下面提供的代码中):

from __future__ import print_function

from prettytable import PrettyTable
t = PrettyTable(['Name               ', '   Age'])
t.align['Name               '] = 'l'
t.align['   Age'] = 'r'
t.hrules = 1
t.add_row(['Alice', 24])
print(t)

#do some work

t.add_row(['Bob', 19])
print( "\n".join(t.get_string().splitlines()[-2:]) )

#do some work

t.add_row(['AliceInWonderland', 1019])
print( "\n".join(t.get_string().splitlines()[-2:]) )

上面的代码生成的输出也适用于 1019 年的“AliceInWonderland”:D:

+---------------------+--------+
| Name                |    Age |
+---------------------+--------+
| Alice               |     24 |
+---------------------+--------+
| Bob                 |     19 |
+---------------------+--------+
| AliceInWonderland   |   1019 |
+---------------------+--------+

【讨论】:

非常感谢您将它们放在一起。有效!特别感谢乔希和他的想法print "\n".join(t.get_string().splitlines()[-2:])【参考方案2】:

你可以这样做:

print "\n".join(t.get_string().splitlines()[-2:])

将脚本的最后一行替换为您想要的结果:

+-------+-----+
|  Name | Age |
+-------+-----+
| Alice |  24 |
+-------+-----+
|  Bob  |  19 |
+-------+-----+

正如 grr 所说,您还可以使用 t.align['Name'] = 'l' 左对齐 Name 列。

+-------+-----+
|  Name | Age |
+-------+-----+
| Alice |  24 |
+-------+-----+
| Bob   |  19 |
+-------+-----+

【讨论】:

['AliceInWonderland', '1024'] 怎么样? 这确实有效。有没有办法指定列宽,以便 ['AliceInWonderland', '1024'] 不会弄乱列宽? 如果您插入任何大于第一行的元素,无论是姓名还是年龄,宽度都会中断。 您可以指定right_padding_widtht 上的属性或作为get_string 的kwarg),但您必须跟踪打印时需要添加多少填充每一行,因为似乎没有办法指定最小列宽。 如果我希望列名称为 20 个字符宽,print "\n".join(t.get_string().splitlines()[-2:]) 将如何改变?【参考方案3】:

您可以使用以下命令打印最后两行:

print t[-2:]

要将Name 字段设置为左对齐,只需使用align 样式选项:

t.align['Name'] = 'l'
print t
+-------+-----+
| Name  | Age |
+-------+-----+
| Alice |  24 |
| Bob   |  19 |
+-------+-----+

要在每个条目之间打印一行+-----+-----+,请将hrules 样式选项设置为1:

t.hrules = 1
print t
+-------+-----+
| Name  | Age |
+-------+-----+
| Alice |  24 |
+-------+-----+
| Bob   |  19 |
+-------+-----+

如果您不希望每次都打印标题,可以将header 样式选项设置为False

t.header = False
print t
+-------+----+
| Alice | 24 |
+-------+----+
| Bob   | 19 |
+-------+----+

PrettyTable Tutorials Wiki 中提供了几个很好的示例,涵盖了您所要求的内容,更多示例

【讨论】:

我尝试使用它而不是示例中的最后一行,但得到了相同的结果。 如果您不想显示标题,您可以将t.header 设置为 False,但您必须在打印完所有下游工作后更改此设置。 我的意思是我在示例中使用了print t[-2:] 而不是print t,但得到了相同的结果。 只有两个条目。如果您继续添加条目,结果将是仅打印最后两个条目。例如,如果您添加另一个条目 ['Tina', 22] 并调用 print t[-2:],您将只看到 Bob 和 Tina 的条目 您是在尝试就地构建表格,还是只是将最近的更改可视化?【参考方案4】:

您可以做的是在每次打印之前清洁屏幕并每次重新绘制整个表格。我认为结果会非常接近你描述的,看看它是什么样子你可以试试这个:

import time
from prettytable import PrettyTable

t = PrettyTable(['Name', 'Age'])
t.add_row(['Alice', 24])

for _ in range(10):
    t.add_row(['Alice', 24])
    print("\033c")
    print(t)
    time.sleep(1)

神奇的是print("\033c"),我不确定它的便携性,如果它不起作用,您可以寻找清除特定系统终端的方法。

【讨论】:

我想这个“解决方案”不是所要求的,但你永远不知道,所以我很想看到这个问题的作者对它的回应以及他决定哪个答案值得被接受...

以上是关于如何在控制台中向已打印的表中添加新行?的主要内容,如果未能解决你的问题,请参考以下文章

如何在SQL中向表中添加“X”行?

在uwp中向数据网格添加新行时如何自动开始编辑?

使用 form-repeater 在填充的表中添加新行需要很长时间(10-15 秒) - jQuery

用sql脚本,进行向已创建好的表中,省及所对应的城市的表 数据的新增

如何使用javascript从数据库中向动态表中添加不同的列

使用复合键的许多人:如何在实体之间的表中添加元素?