2012-03-02 3 views
159

Я довольно новичок в 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 

У меня есть подозрение, что там должна быть структура данных для этого, но я не могу найти его. Я попытался использовать словарь и форматирование печати, я попытался использовать петли с отступом, и я попробовал печать в виде строк.

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

+1

+1, я просто пытался сделать то же самое прошлой ночью beautifultable в. Вы просто пытаетесь распечатать в командной строке или используете графический интерфейс? –

+0

Просто печать в командной строке. Тем не менее, он должен передать блок-тест, поэтому форматирование здесь очень важно. – casper

+2

Возможный дубликат [Печать табличных данных в Python] (http://stackoverflow.com/questions/5122347/printing-tabular-data-in-python) –

ответ

114

Некоторые одноранговой код 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() и Format Specification Mini-Language.

+3

Если вы используете python2.6, не забудьте добавить индекс team_list в row_format: row_format = "{0:> 15} {1:> 15} {2:> 15}" –

+0

u '{:> 15}' для юникодов – ademar111190

+0

Если данные в теле больше, чем заголовки, вы можете установить ширину столбца на основе первой строки данных. для t в данных [0]: row_format + = "{: <" + str (len (t) +5) + "}" – morgantaschuk

8

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

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

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

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

От линии 53 с:

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

Я бы попробовать перебрать список и использовать форматчик CSV для представляют данные, которые вы хотите.

В качестве разделителя вы можете указать запятые или любые другие символы.

В противном случае, просто цикл по списку и печати "\ т" после каждого элемента

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

+0

Это была моя первоначальная попытка, возможно, это можно сделать, но, похоже, это очень много усилий, чтобы добиться форматирования. – casper

49
>>> 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   
+3

Это выглядит очень многообещающим, спасибо, но я пытаюсь сделать это, не используя больше импортированных библиотек, чем это абсолютно необходимо. – casper

+9

Использование pandas только для форматирования вывода похоже на Overkill (предполагаемый капитал O). –

+38

@NielsBom: придите для форматирования вывода, оставайтесь для анализа данных и моделирования :) – jfs

31

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, что вы намерены использовать предыдущую строку в качестве строки формата и чтобы в указанный формат были помещены следующие данные.

В этом случае я дважды использовал «% -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

241

Есть некоторые легкие и полезные питона пакеты для этой цели:

1. Tabulate: 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 

Табуляция имеет множество опций для указания заголовков и формата таблицы.

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

с texttable вы можете контролировать горизонтальные/Verical выравнивать, стиль границы и типов данных.

Другие варианты:

  • terminaltables легко рисовать таблицы в приложениях/консольных терминалов из списка списков строк. Поддерживает многострочные строки.
  • asciitable Asciitable может читать и писать широкий диапазон форматов таблицы ASCII через встроенные классы чтения расширений.
+6

Я нашел, что tabulate является очень полезным инструментом для создания инструментов CLI, ориентированных на данные. Это, в сочетании с щелчком (клик по установке кликов), и у вас есть реальное тушение. – alexbw

+4

Это замечательно, спасибо. Лично, какой из них вы бы предпочли? –

+0

Блестящий ответ! PrettyTable так хорош - идеальный баланс между двумя другими вариантами. –

8

Обновление ответ 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

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

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 
13

BeautifulTable и Tabulate некоторые из многих пакетов, которые вы можете использовать, чтобы решить вашу проблему.

Вот пример из documentation

>>> from beautifultable import BeautifulTable 
>>> table = BeautifulTable() 
>>> table.column_headers = ["name", "rank", "gender"] 
>>> table.append_row(["Jacob", 1, "boy"]) 
>>> table.append_row(["Isabella", 1, "girl"]) 
>>> table.append_row(["Ethan", 2, "boy"]) 
>>> table.append_row(["Sophia", 2, "girl"]) 
>>> table.append_row(["Michael", 3, "boy"]) 
>>> print(table) 
+----------+------+--------+ 
| name | rank | gender | 
+----------+------+--------+ 
| Jacob | 1 | boy | 
+----------+------+--------+ 
| Isabella | 1 | girl | 
+----------+------+--------+ 
| Ethan | 2 | boy | 
+----------+------+--------+ 
| Sophia | 2 | girl | 
+----------+------+--------+ 
| Michael | 3 | boy | 
+----------+------+--------+ 
+2

Хотя ваш ответ на 100% правильный, он также может стать 100% бесполезным , если эта ссылка перемещена, изменена, объединена в другую или основной сайт просто исчезает ... **: - (** Поэтому, пожалуйста, отредактируйте свой ответ и скопируйте соответствующие шаги из ссылки в свой ответ, тем самым гарантируя ответ за 100% срока службы этого сайта! **; -) ** Вы всегда можете оставьте ссылку в нижней части вашего ответа в качестве источника для вашего материала ... –

Смежные вопросы