Печать списков в виде табличных данных - PullRequest
275 голосов
/ 02 марта 2012

Я довольно новичок в 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 с отступом и пытался печатать как строки.

Я уверен, что должен быть очень простой способ сделать это, но явероятно, пропустил это из-за отсутствия опыта.

Ответы [ 12 ]

419 голосов
/ 14 ноября 2014

Есть несколько легких и полезных пакетов 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  |
+-------+-----+

с помощью текстовой таблицы вы можете управлять горизонтальным / вертикальным выравниванием, стилем границы и типами данных.

Другие опции:

  • Terminaltables Легко рисовать таблицы в приложениях терминала / консоли из списка списков строк. Поддерживает многострочные строки.
  • asciitable Asciitable может читать и записывать широкий спектр форматов таблиц ASCII через встроенные классы расширений Reader.
163 голосов
/ 02 марта 2012

Некоторый специальный код для Python 2.7:

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() и Спецификации формата Mini-Language .

64 голосов
/ 02 марта 2012
>>> 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        
49 голосов
/ 24 сентября 2014

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

% в строке по сути является escape-символоми следующие за ним символы указывают 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

20 голосов
/ 05 августа 2015

Обновление ответа Свена Марнача для работы в 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))
9 голосов
/ 16 июля 2016

Когда я делаю это, мне нравится иметь некоторый контроль над деталями того, как таблица отформатирована.В частности, я хочу, чтобы ячейки заголовка имели другой формат, чем ячейки тела, а ширина столбцов таблицы должна быть такой же широкой, как каждая из них.Вот мое решение:

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

Вот вывод:

                   | 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
8 голосов
/ 02 марта 2012

Я думаю это - это то, что вы ищете.

Это простой модуль, который просто вычисляет максимальную требуемую ширину для записей таблицы, а затем просто использует rjust и ljust , чтобы сделать красивую печать данных.

Если вы хотите, чтобы ваш левый заголовок был выровнен по правому краю, просто измените этот вызов:

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

Из строки 53 с:

 print >> out, row[0].rjust(col_paddings[0] + 1),
5 голосов
/ 07 мая 2018

Чистый Питон 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
3 голосов
/ 09 сентября 2018

Простой способ сделать это состоит в том, чтобы перебрать все столбцы, измерить их ширину, создать 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
3 голосов
/ 30 июля 2018

Следующая функция создаст запрошенную таблицу (с numpy или без) с Python 3 (возможно, также Python 2). Я выбрал ширину каждого столбца, соответствующую ширине самого длинного имени команды. Вы можете изменить его, если хотите использовать длину имени команды для каждого столбца, но это будет более сложным.

Примечание: для прямого эквивалента в Python 2 вы можете заменить zip на izip из itertools.

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.

Ссылки:

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...