将列表打印为表格数据

2024-11-22 08:48:00
admin
原创
155
摘要:问题描述:我对 Python 还很陌生,现在正在努力格式化我的数据以便打印输出。我有一个用于两个标题的列表和一个应为表格内容的矩阵。如下所示:teams_list = ["Man Utd", "Man City", "T Hotspur"] data...

问题描述:

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

我有一个用于两个标题的列表和一个应为表格内容的矩阵。如下所示:

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

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

现在,我想以表格形式表示它,如下所示:

曼联曼城热刺队
曼联100
曼城110
热刺队012

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

我确信一定有一种非常简单的方法可以做到这一点,但我可能由于缺乏经验而错过了它。


解决方案 1:

有一些轻量且实用的 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. 文本表: 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  |
+-------+-----+

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

4.termtableshttps://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  |
+-------+-----+

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

其他选择:

  • terminaltables轻松地从字符串列表列表中绘制终端/控制台应用程序中的表格。支持多行。

  • asciitable Asciitable 可以通过内置的扩展阅读器类读取和写入各种 ASCII 表格式。

解决方案 2:

一些临时代码:

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

这依赖于str.format()格式规范小语言。

解决方案 3:

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

解决方案 4:

Python 实际上使这变得相当容易。

类似于

for i in range(10):
    print '%-12i%-12i' % (10 ** i, 20 ** i)

将有输出

1           1           
10          20          
100         400         
1000        8000        
10000       160000      
100000      3200000     
1000000     64000000    
10000000    1280000000  
100000000   25600000000
1000000000  512000000000

字符串中的 % 本质上是一个转义字符,其后的字符告诉 Python 数据应采用哪种格式。字符串外部和之后的 % 告诉 Python 您打算使用前一个字符串作为格式字符串,并且后面的数据应采用指定的格式。

在本例中,我使用了两次“%-12i”。分解每个部分:

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

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

解决方案 5:

更新 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))

解决方案 6:

我知道我来晚了,但我刚刚为此创建了一个库,我认为它真的很有用。它非常简单,这就是我认为你应该使用它的原因。它被称为TableIT

基本使用

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

然后导入它:

import TableIt

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

table = [
    [4, 3, "Hi"],
    [2, 1, 808890312093],
    [5, "Hi", "Bye"]
]

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

TableIt.printTable(table)

这是您获得的输出:

+--------------------------------------------+
| 4            | 3            | Hi           |
| 2            | 1            | 808890312093 |
| 5            | Hi           | Bye          |
+--------------------------------------------+

字段名称

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


TableIt.printTable(table, useFieldNames=True)

由此你将获得:

+--------------------------------------------+
| 4            | 3            | Hi           |
+--------------+--------------+--------------+
| 2            | 1            | 808890312093 |
| 5            | Hi           | Bye          |
+--------------------------------------------+

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

import TableIt

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

TableIt.print(myList, useFieldNames=True)

从那开始:

+-----------------------------------------------+
| Name                  | Email                 |
+-----------------------+-----------------------+
| Richard               | richard@fakeemail.com |
| Tasha                 | tash@fakeemail.com    |
+-----------------------------------------------+

或者你可以这样做:

import TableIt

myList = [
    ["", "a", "b"],
    ["x", "a + x", "a + b"],
    ["z", "a + z", "z + b"]
]

TableIt.printTable(myList, useFieldNames=True)

由此你可以获得:

+-----------------------+
|       | a     | b     |
+-------+-------+-------+
| x     | a + x | a + b |
| z     | a + z | z + b |
+-----------------------+

颜色

您还可以使用颜色。

您可以使用颜色选项(默认设置为无)并指定 RGB 值来使用颜色。

使用上面的例子:

import TableIt

myList = [
    ["", "a", "b"],
    ["x", "a + x", "a + b"],
    ["z", "a + z", "z + b"]
]

TableIt.printTable(myList, useFieldNames=True, color=(26, 156, 171))

然后你会得到:

在此处输入图片描述

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

更多信息

更多信息请查看GitHub 页面

解决方案 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)

结果,你会得到一张整洁的桌子,就是这样。
在此处输入图片描述

解决方案 8:

尝试丰富: 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)

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

在此处输入图片描述

解决方案 9:

一个简单的方法是循环遍历所有列,测量它们的宽度,为最大宽度创建一个 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))

你可以像这样使用它:

>>> print_table(table)

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

解决方案 10:

当我这样做时,我希望能够控制表格格式的细节。特别是,我希望标题单元格的格式与正文单元格不同,并且表格列的宽度仅与每个列所需的宽度相同。这是我的解决方案:

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]] \n                 + 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}', '
', ' | ')

输出如下:

                   | 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

解决方案 11:

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

for row in table_data:
    print("{: >20} {: >20} {: >20}".format(*row))

输出:

               1                  2                3
               4                  5                6
               7                  8                9

其中 f 字符串格式化

  1. “>” 用于右对齐

  2. “<”用于左对齐

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

解决方案 12:

纯 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 = '
'.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

解决方案 13:

我想这就是你要找的。

这是一个简单的模块,只需计算表格条目所需的最大宽度,然后使用rjust和ljust对数据进行漂亮的打印。

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

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

从第 53 行开始:

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

解决方案 14:

另一个无库解决方案,它考虑每列中最长的元素:

def pretty_print_table(rows, line_between_rows=True):
  """
  Example Output
  ┌──────┬─────────────┬────┬───────┐
  │ True │ short       │ 77 │ catty │
  ├──────┼─────────────┼────┼───────┤
  │ 36   │ long phrase │ 9  │ dog   │
  ├──────┼─────────────┼────┼───────┤
  │ 8    │ medium      │ 3  │ zebra │
  └──────┴─────────────┴────┴───────┘
  """

  # find the max length of each column
  max_col_lens = list(map(max, zip(*[(len(str(cell)) for cell in row) for row in rows])))

  # print the table's top border
  print('┌' + '┬'.join('─' * (n + 2) for n in max_col_lens) + '┐')

  rows_separator = '├' + '┼'.join('─' * (n + 2) for n in max_col_lens) + '┤'

  row_fstring = ' │ '.join("{: <%s}" % n for n in max_col_lens)

  for i, row in enumerate(rows):
    print('│', row_fstring.format(*map(str, row)), '│')
    
    if line_between_rows and i < len(rows) - 1:
      print(rows_separator)

  # print the table's bottom border
  print('└' + '┴'.join('─' * (n + 2) for n in max_col_lens) + '┘')

例子:

rows = [
  [True, "short", 77, "catty"],
  [36, "long phrase", 9, "dog"],
  [8, 'medium', 3, "zebra"],
]

pretty_print_table(rows)

'''
┌──────┬─────────────┬────┬───────┐
│ True │ short       │ 77 │ catty │
├──────┼─────────────┼────┼───────┤
│ 36   │ long phrase │ 9  │ dog   │
├──────┼─────────────┼────┼───────┤
│ 8    │ medium      │ 3  │ zebra │
└──────┴─────────────┴────┴───────┘
'''

pretty_print_table(rows, line_between_rows=False)

'''
┌──────┬─────────────┬────┬───────┐
│ True │ short       │ 77 │ catty │
│ 36   │ long phrase │ 9  │ dog   │
│ 8    │ medium      │ 3  │ zebra │
└──────┴─────────────┴────┴───────┘
'''

解决方案 15:

以下函数将使用 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)

这将产生下表:

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

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

参考:

解决方案 16:

对于简单的情况,您只需使用现代字符串格式(简化的Sven的答案)即可

f'{column1_value:15} {column2_value}'::

table = {
    'Amplitude': [round(amplitude, 3), 'm³/h'],
    'MAE': [round(mae, 2), 'm³/h'],
    'MAPE': [round(mape, 2), '%'],
}

for metric, value in table.items():
    print(f'{metric:14} : {value[0]:>6.3f} {value[1]}')

输出:

Amplitude      :  1.438 m³/h
MAE            :  0.171 m³/h
MAPE           : 27.740 %

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

解决方案 17:

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

print("Titlex    Titley    Titlez")
for x, y, z in data:
    print(x, "    ", y, "    ", z)

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

#Column headers
print("", end="    ")
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="    ")
    for entry in row:
        print(entry, end="    ")
    print()

输出:

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

但这似乎不再比其他答案更简单,也许好处是它不需要更多导入。但@campkeith 的答案已经满足了这一点,而且更强大,因为它可以处理更多种类的标签长度​​。

解决方案 18:

我会尝试循环遍历列表并使用 CSV 格式化程序来表示您想要的数据。

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

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

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

解决方案 19:

我找到了一个更好的,可以节省很多空间。

table = [
    ['number1', 'x', 'name'],
    ["4x", "3", "Hi"],
    ["2", "1", "808890312093"],
    ["5", "Hi", "Bye"]
]
column_max_width = [max(len(row[column_index]) for row in table) for column_index in range(len(table[0]))]
row_format = ["{:>"+str(width)+"}" for width in column_max_width]
for row in table:
    print("|".join([print_format.format(value) for print_format, value in zip(row_format, row)]))

输出:

number1| x|        name
     4x| 3|          Hi
      2| 1|808890312093
      5|Hi|         Bye

解决方案 20:

要创建一个简单的表格,请terminaltables打开终端或命令提示符并运行pip install terminaltables

您可以按如下方式打印 Python 列表:

from terminaltables import AsciiTable

l = [
  ['Head', 'Head'],
  ['R1 C1', 'R1 C2'],
  ['R2 C1', 'R2 C2'],
  ['R3 C1', 'R3 C2']
]

table = AsciiTable(l)
print(table.table)

解决方案 21:

print(a, " ", b)最小无依赖左对齐 Python 实现,与任何现有语句向后兼容:

class AlignedPrinter:
    def __init__(self):
        self._col_widths = {}
        self._lines = []

    def __del__(self):
        self.aligned_print()

    def print(self, *args):
        line = ' '.join([str(x) for x in args])
        cols = line.split('    ')
        self._lines.append(cols)
        for i in range(len(cols)):
            self._col_widths[i] = max(len(cols[i]), self._col_widths.get(i, 0))

    def aligned_print(self):
        for line in self._lines:
            aligned = []
            for i in range(len(line)):
                col = line[i]
                aligned.append(col + ' ' * (self._col_widths[i] - len(col)))
            print(' '.join(aligned))
        self.__init__()

这将允许您轻松转换大多数 基于工作的打印件:

print('    ', '    '.join(teams_list))
for i in range(len(data)):
    print(teams_list[i], '    ', '    '.join(str(x) for x in data[i]))

和:

a = AlignedPrinter()
a.print('    ', '    '.join(teams_list))
for i in range(len(data)):
    a.print(teams_list[i], '    ', '    '.join(str(x) for x in data[i]))
a.aligned_print()

为您提供:

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

解决方案 22:

matrepr在标记矩阵方面做得很好:

from matrepr import mprint

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

mprint(data, title=False, row_labels=teams, col_labels=teams)
             Man Utd    Man City    T Hotspur
          ┌                                    ┐
  Man Utd │     1          2            1      │
 Man City │     0          1            0      │
T Hotspur │     2          4            2      │
          └                                    ┘

除了 numpy 数组之外,还可以使用稀疏矩阵(scipy、pydata),并输出为 HTML 和 Latex。

解决方案 23:

list1 = [1, 2, 3]
list2 = [10, 20, 30]

l = []

for i in range(0, len(list1)):
    l.append(list1[i]), l.append(list2[i])

# print(l)

for i in range(0, len(l), 2):
    print(l[i], "", l[i + 1])
相关推荐
  政府信创国产化的10大政策解读一、信创国产化的背景与意义信创国产化,即信息技术应用创新国产化,是当前中国信息技术领域的一个重要发展方向。其核心在于通过自主研发和创新,实现信息技术应用的自主可控,减少对外部技术的依赖,并规避潜在的技术制裁和风险。随着全球信息技术竞争的加剧,以及某些国家对中国在科技领域的打压,信创国产化显...
工程项目管理   1565  
  为什么项目管理通常仍然耗时且低效?您是否还在反复更新电子表格、淹没在便利贴中并参加每周更新会议?这确实是耗费时间和精力。借助软件工具的帮助,您可以一目了然地全面了解您的项目。如今,国内外有足够多优秀的项目管理软件可以帮助您掌控每个项目。什么是项目管理软件?项目管理软件是广泛行业用于项目规划、资源分配和调度的软件。它使项...
项目管理软件   1354  
  信创国产芯片作为信息技术创新的核心领域,对于推动国家自主可控生态建设具有至关重要的意义。在全球科技竞争日益激烈的背景下,实现信息技术的自主可控,摆脱对国外技术的依赖,已成为保障国家信息安全和产业可持续发展的关键。国产芯片作为信创产业的基石,其发展水平直接影响着整个信创生态的构建与完善。通过不断提升国产芯片的技术实力、产...
国产信创系统   21  
  信创生态建设旨在实现信息技术领域的自主创新和安全可控,涵盖了从硬件到软件的全产业链。随着数字化转型的加速,信创生态建设的重要性日益凸显,它不仅关乎国家的信息安全,更是推动产业升级和经济高质量发展的关键力量。然而,在推进信创生态建设的过程中,面临着诸多复杂且严峻的挑战,需要深入剖析并寻找切实可行的解决方案。技术创新难题技...
信创操作系统   27  
  信创产业作为国家信息技术创新发展的重要领域,对于保障国家信息安全、推动产业升级具有关键意义。而国产芯片作为信创产业的核心基石,其研发进展备受关注。在信创国产芯片的研发征程中,面临着诸多复杂且艰巨的难点,这些难点犹如一道道关卡,阻碍着国产芯片的快速发展。然而,科研人员和相关企业并未退缩,积极探索并提出了一系列切实可行的解...
国产化替代产品目录   28  
热门文章
项目管理软件有哪些?
云禅道AD
禅道项目管理软件

云端的项目管理软件

尊享禅道项目软件收费版功能

无需维护,随时随地协同办公

内置subversion和git源码管理

每天备份,随时转为私有部署

免费试用