목록을 표 형식의 데이터로 인쇄


366

저는 파이썬을 처음 접했고 인쇄 출력을 위해 데이터를 멋지게 형식화하는 데 어려움을 겪고 있습니다.

두 개의 제목에 사용되는 하나의 목록과 테이블의 내용이어야하는 행렬이 있습니다. 이렇게 :

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-loops를 시도했으며 문자열로 인쇄를 시도했습니다.

이 작업을 수행하는 매우 간단한 방법이 있어야하지만 경험 부족으로 인해 누락 될 수 있습니다.


1
+1, 나는 지난 밤에 똑같은 일을하려고했습니다. 명령 행에 인쇄하려고하거나 GUI 모듈을 사용하고 있습니까?
HellaMad

명령 행으로 인쇄하기 만하면됩니다. 그러나 단위 테스트 사례를 통과해야하므로 여기에서 서식이 매우 중요합니다.
hjweide



행과 열 레이블이 동일하므로 여기의 요구 사항은 매우 전문화되어 있습니다. 따라서이 특별한 경우 임시 코드는 이것이 얼마나 쉬운지를 보여주는 좋은 예입니다. 그러나 다른 솔루션은보다 일반적인 테이블 표시에 더 좋습니다.
nealmcb

답변:


189

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()하고 형식 사양 미니 언어 .


3
python2.6을 사용하는 경우 row_format에 team_list 인덱스를 추가해야합니다. row_format = "{0 :> 15} {1 :> 15} {2 :> 15}"
Luis Muñoz

1
본문의 데이터가 헤더보다 큰 경우 첫 번째 데이터 행을 기준으로 열 너비를 설정할 수 있습니다. 데이터에 대한 t [0] + ROW_FORMAT = "{<"+ STR (LEN (t) +5) + "}"
morgantaschuk

587

이 목적을 위해 가볍고 유용한 파이썬 패키지가 있습니다 :

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

텍스트 테이블을 사용하면 가로 / 세로 정렬, 테두리 스타일 및 데이터 형식을 제어 할 수 있습니다.

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 테이블 형식을 읽고 쓸 수 있습니다.

13
tabulate는 데이터 중심 CLI 도구를 작성하는 데 매우 유용한 도구라는 것을 알았습니다. 클릭 (핍 설치 클릭)과 결합하면 실제로 스튜가 생깁니다.
alexbw

4
훌륭합니다, 감사합니다. 개인적으로,이 세 가지 중에서 어떤 것을 선호하십니까?
Jim Raynor

훌륭한 답변! PrettyTable은 매우 훌륭합니다. 다른 두 옵션 사이의 완벽한 균형입니다.
edesz

2
terminaltables는 중국어, 영어 이외의 다른 언어에
유용

5
나는 방금 메인 패키지와 IMO "beautifultable"-최상의 유지 관리, 좋은 API 및 도코, 컬러 지원을 가지고 놀았습니다. "texttable"-훌륭하고 유지 보수가 잘되는 API이지만 색상을 사용하면 테이블이 정렬되지 않습니다. "터미널 테이블"-코드 예제를 통해서만 가능합니다. "PrettyTable"-알았지 만 오래된 테이블 '제목'이 작동하지 않습니다. "Tabulate"-양호하지만 열 맞춤 coalign키워드는 공식 pypi 릴리스에서 지원되지 않습니다. "tableprint"-평균, 복잡한 API, 일반적인 사용 예는 충분하지 않습니다.
abulka

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

6
이것은 매우 유망한 것으로 보이지만 절대 필요한 것보다 더 가져온 라이브러리를 사용하지 않고이 작업을 수행하려고합니다.
hjweide

26
출력 형식으로 팬더를 사용하는 것은 Overkill (capital O 의도)과 같습니다.
Niels Bom

66
@NielsBom : 출력 형식화, 데이터 분석 및 모델링 유지 :)
jfs

30
@JFSebastian 나에게 그것은 "출력 포맷을 위해 와서, 내 컴퓨터가 헤어 드라이어처럼 들리는 10 분의 numpy 편집 때문에 소리 지르지 않는다";-)
Niels Bom

4
@NielsBom : pip install numpy대부분의 플랫폼에서 바이너리 휠을 사용합니다 (컴파일 없음) . 분명히 그 이전에도 다른 바이너리 설치 옵션을 사용할 수있었습니다.
jfs

68

파이썬은 실제로 이것을 아주 쉽게 만듭니다.

같은 것

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


이 답변을 통해 내가 찾던 것을 찾을 수있었습니다. 파이썬 3, 나는처럼 사용하여 결국 print('%-20.2f' % position['deg'], '%-17.2f' % position['v2'])어디에 .2플로트의 지정 정밀도f
로스

25

Python 3.4에서 작동하도록 Sven Marnach의 답변 업데이트 :

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

이 작업을 수행 할 때 테이블의 형식 지정 방법에 대한 세부 정보를 제어하고 싶습니다. 특히 헤더 셀이 본문 셀과 다른 형식을 갖기를 원하며 테이블 열 너비는 각 너비만큼 넓어야합니다. 내 해결책은 다음과 같습니다.

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

나는 이것이 당신이 찾고있는 것이라고 생각 합니다 .

테이블 항목에 필요한 최대 너비를 계산 한 다음 rjustljust 를 사용 하여 데이터를 예쁘게 인쇄 하는 간단한 모듈입니다 .

왼쪽 머리글 오른쪽을 정렬하려면이 호출을 변경하십시오.

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

53 행 :

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

8

나는 파티에 늦었다는 것을 알고 있지만 실제로 도움이 될만한 라이브러리를 만들었습니다. 그것은 매우 간단합니다. 그래서 나는 당신이 그것을 사용해야한다고 생각합니다. 이를 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 |
+-----------------------+

그림 물감

색상을 사용할 수도 있습니다.

색상 옵션 ( 기본적으로 None으로 설정 됨 )을 사용하고 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 페이지를 확인하십시오


Table 그것은 정말 좋은 도구입니다. 간단하지만 강력합니다. 내가 생각하는 유일한 단점은 TableIt은 라이센스를 선언하지 않았다
Endle_Zhenbo

트윗 담아 가기 고마워요. 최대한 빨리 노력하겠습니다!
BeastCoder

@ Endle_Zhenbo, 나는 그것이 오래되었다는 것을 알고 있지만 마침내 프로젝트에 라이센스를 부여했습니다.
BeastCoder

7

순수한 파이썬 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

5

이를 수행하는 간단한 방법은 모든 열을 반복하고 너비를 측정하고 해당 최대 너비에 대한 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

다음 함수는 Python 3 (아마도 Python 2)으로 요청 된 테이블 (numpy를 사용하거나 사용하지 않고)을 만듭니다. 가장 긴 팀 이름의 너비와 일치하도록 각 열의 너비를 설정했습니다. 각 열에 팀 이름 길이를 사용하려는 경우 수정할 수 있지만 더 복잡합니다.

참고 : 대체 할 수 파이썬 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.

참고 문헌 :


2

목록을 반복하고 CSV 포맷터를 사용하여 원하는 데이터를 나타냅니다.

탭, 쉼표 또는 다른 문자를 구분 기호로 지정할 수 있습니다.

그렇지 않으면 목록을 반복하고 각 요소 다음에 "\ t"를 인쇄하십시오.

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


이것은 나의 초기 시도였습니다. 아마도 가능하지만 형식을 완벽하게 만드는 데 많은 노력이 필요한 것 같습니다.
hjweide

2

간단한 열을 출력하는 방법을 찾고 있다는 것을 알았습니다. 소란없는 열이 필요한 경우 다음을 사용할 수 있습니다.

print("Titlex\tTitley\tTitlez")
for x, y, z in data:
    print(x, "\t", y, "\t", z)

편집 : 나는 가능한 한 단순하려고 노력했기 때문에 팀 목록을 사용하는 대신 수동으로 몇 가지 작업을 수행했습니다. OP의 실제 질문으로 일반화하려면 :

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

출력 :

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

그러나 이것은 더 이상 다른 답변보다 더 단순 해 보이지 않으며 더 이상 수입이 필요하지 않은 이점이 있습니다. 그러나 @campkeith의 대답은 이미 그것을 충족했으며 더 다양한 레이블 길이를 처리 할 수 ​​있으므로 더욱 강력합니다.


당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.