Listeleri Tablo Verileri Olarak Yazdırma


366

Python için oldukça yeniyim ve şimdi verilerimi basılı çıktı için güzel bir şekilde biçimlendirmekle uğraşıyorum.

İki başlık için kullanılan bir liste ve tablonun içeriği olması gereken bir matris var. Şöyle ki:

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

Başlık adlarının mutlaka aynı uzunluklarda olmadığını unutmayın. Veri girişlerinin tümü tamsayılardır.

Şimdi, bunu bir tablo biçiminde, şöyle bir şeyle temsil etmek istiyorum:

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

Bunun için bir veri yapısı olması gerektiğine dair bir önsezim var ama bulamıyorum. Bir sözlük kullanmayı ve baskıyı biçimlendirmeyi denedim, girinti için döngüler denedim ve dizeler olarak yazdırmayı denedim.

Bunu yapmak için çok basit bir yol olmalı eminim, ama muhtemelen deneyim eksikliği nedeniyle özlüyorum.


1
+1, sadece dün gece aynı şeyi yapmaya çalışıyordum. Sadece komut satırına yazdırmaya mı çalışıyorsunuz yoksa bir GUI modülü mü kullanıyorsunuz?
HellaMad

Sadece komut satırına yazdırmak. Bununla birlikte, bir birim test vakasını geçmesi gerekir, bu nedenle biçimlendirme burada oldukça önemlidir.
hjweide



Buradaki gereksinimin oldukça özel olduğunu unutmayın, çünkü satır ve sütun etiketleri aynıdır. Dolayısıyla bu özel durum için, ad-hoc kodu bunun ne kadar kolay olabileceğinin güzel bir örneğidir. Ancak buradaki diğer çözümler daha genel tablo görüntüsü için daha iyi olabilir.
nealmcb

Yanıtlar:


189

Python 2.7 için bazı geçici kod:

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

Bu str.format(), Biçim Belirtimi Mini Dili'ne dayanır .


3
Python2.6 kullanıyorsanız row_format üzerinde team_list dizini eklemeyi unutmayın: row_format = "{0:> 15} {1:> 15} {2:> 15}"
Luis Muñoz

1
Gövdedeki veriler üstbilgilerden daha büyükse, sütun genişliğini ilk veri satırına göre ayarlayabilirsiniz. verilerde t için [0]: row_format + = "{: <" + str (len (t) +5) + "}"
morgantaschuk

587

Bu amaçla bazı hafif ve kullanışlı python paketleri vardır:

1. tablo : 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 üstbilgileri ve tablo biçimini belirtmek için birçok seçeneğe sahiptir.

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 veritabanından veri okuma seçeneklerine sahiptir. Ayrıca, verilerin alt kümesini seçebilir, tabloyu sıralayabilir ve tablo stillerini değiştirebilirsiniz.

3. yazılabilir : 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 ile yatay / dikey hizalamayı, kenarlık stilini ve veri türlerini kontrol edebilirsiniz.

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

texttable ile yatay / dikey hizalamayı, kenarlık stilini ve veri türlerini kontrol edebilirsiniz.

Diğer seçenekler:

  • terminal tabloları Dizeler listesinden terminal / konsol uygulamalarında tabloları kolayca çizin. Çok satırlı satırları destekler.
  • asciitable Asciitable, dahili Extension Reader Sınıfları aracılığıyla çok çeşitli ASCII tablo formatlarını okuyabilir ve yazabilir.

13
Tabulate veri merkezli CLI araçları oluşturmak için çok yararlı bir araç olarak buldum. Bu, tıklama ile birlikte (pip install click) ve gerçek bir güveç var.
alexbw

4
Bu harika, teşekkürler. Şahsen, bu üçü arasından hangisini tercih edersiniz?
Jim Raynor

Mükemmel cevap! PrettyTable çok iyi - diğer iki seçenek arasındaki mükemmel denge.
edesz

2
terminaltables Çince, belki de diğer İngilizce olmayan diller için
iyidir

5
Sadece ana paketleri ve IMO "beautifultable" ile oynadım - en iyi, bakımı yapılmış, iyi API ve doco, renkli desteği. "texttable" - güzel, bakımlı, iyi API ancak renkli kullanım kullanımı tabloları hizalamadan atar. "terminaltables" - iyi, sadece kod örnekleri ile doco. "PrettyTable" - tamam, ama eski, tablo 'başlıklar' benim için çalışmıyor. "Tabulate" - iyi, ancak sütun hizalama coalignanahtar kelimesi resmi pypi sürümünde desteklenmiyor. "tableprint" - ortalama, API kompleksi, yeterli yaygın kullanım örneği yok.
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
Bu çok umut verici görünüyor, teşekkürler, ama kesinlikle gerekenden daha fazla ithal kitaplık kullanmadan yapmaya çalışıyorum.
hjweide

26
Pandaları yalnızca çıktı biçimlendirmesi için kullanmak Overkill (başkent O amaçlı) gibi görünüyor.
Niels Bom

66
@NielsBom: çıktı biçimlendirme için gel, veri analizi ve modelleme için kal :)
jfs

30
@JFSebastian bana daha çok "çıktı biçimlendirme için gel, bilgisayarımı bir saç kurutma makinesi gibi ses yapan 10 dakikalık numpy derleme nedeniyle çığlık kaçmak" gibiydi ;-)
Niels Bom

4
@NielsBom: pip install numpyartık çoğu platformda ikili tekerlekler kullanıyor (derleme yok) . Açıkçası, bundan önce bile diğer ikili kurulum seçenekleri mevcuttu.
jfs

68

Python aslında bunu oldukça kolaylaştırıyor.

Gibi bir şey

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

çıktıya sahip olacak

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

Dize içindeki% değeri aslında bir kaçış karakteri ve onu izleyen karakterler python'a verilerin ne tür bir formatta olması gerektiğini söyler. Dizenin dışındaki ve arkasındaki%, python'a, önceki dizeyi biçim dizesi olarak kullanmayı planladığınızı ve aşağıdaki verilerin belirtilen biçime yerleştirileceğini söylüyor.

Bu durumda iki kez "% -12i" kullandım. Her bir parçayı parçalamak için:

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

Dokümanlardan: https://docs.python.org/2/library/stdtypes.html#string-formatting


Bu cevap beni aradığımı bulma yolunda gitti! Piton 3 için, ben gibi kullandığı ortaya çıktı print('%-20.2f' % position['deg'], '%-17.2f' % position['v2'])nerede .2float belirtir hassasf
Ross

25

Sven Marnach'ın Python 3.4'teki çalışma yanıtını güncelleme:

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

Bunu yaptığımda, tablonun nasıl biçimlendirildiğiyle ilgili ayrıntılar üzerinde biraz kontrol sahibi olmayı seviyorum. Özellikle, başlık hücrelerinin vücut hücrelerinden farklı bir biçime sahip olmasını ve tablo sütun genişliklerinin her birinin olması gerektiği kadar geniş olmasını istiyorum. İşte benim çözümüm:

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

İşte çıktı:

                   | 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

Bence bu aradığınız şey.

Tablo girişleri için gereken maksimum genişliği hesaplayan basit bir modül ve sadece rjust ve ljust verilerin oldukça baskı yapmak.

Sol başlığınızın sağa hizalanmasını istiyorsanız bu aramayı değiştirin:

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

53. satırdan:

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

8

Partiye geç kaldığımı biliyorum, ama bunun için gerçekten yardımcı olabileceğini düşündüğüm bir kütüphane yaptım. Son derece basit, bu yüzden kullanmanız gerektiğini düşünüyorum. Buna TableIT denir .

Temel Kullanım

Kullanmak için, önce GitHub Sayfasındaki indirme talimatlarını izleyin .

Ardından içe aktarın:

import TableIt

Ardından, her bir iç listenin bir satır olduğu listelerin bir listesini yapın:

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

Sonra tek yapmanız gereken yazdırmak:

TableIt.printTable(table)

Bu elde ettiğiniz çıktıdır:

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

Alan İsimleri

İsterseniz alan adlarını kullanabilirsiniz (alan adlarını kullanmıyorsanız, useFieldNames = False (varsayılan olarak buna ayarlandığından) demeniz gerekmez ):


TableIt.printTable(table, useFieldNames=True)

Ondan alacaksınız:

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

Bunun için başka kullanımlar da vardır, örneğin bunu yapabilirsiniz:

import TableIt

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

TableIt.print(myList, useFieldNames=True)

Bundan:

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

Veya şunları yapabilirsiniz:

import TableIt

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

TableIt.printTable(myList, useFieldNames=True)

Ve bundan elde edersiniz:

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

Renkler

Renkleri de kullanabilirsiniz.

Renk seçeneğini, renk seçeneğini ( varsayılan olarak Yok olarak ayarlanmıştır ) kullanarak ve RGB değerleri belirterek kullanırsınız.

Yukarıdaki örneği kullanarak:

import TableIt

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

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

Sonra alacaksınız:

resim açıklamasını buraya girin

Baskı renklerinin sizin için çalışmayabileceğini, ancak renkli metin basan diğer kitaplıklarla aynı şekilde çalıştığını lütfen unutmayın. Test ettim ve her renk çalışıyor. Mavi, varsayılanı kullanırken olduğu gibi dağınık değildir34m ANSI kaçış dizisini değildir (bunun ne olduğunu bilmiyorsanız bunun önemi yoktur). Her neyse, her bir sistem varsayılanı değil, her rengin RGB değeri olduğu gerçeğinden geliyor.

Daha fazla bilgi

Daha fazla bilgi için GitHub Sayfasını kontrol edin


TableIt gerçekten güzel bir araç. Basit ama güçlü. Sanırım tek dezavantajı TableIt LİSANS ilan
etmedi

@Endle_Zhenbo Hey! Çok teşekkürler, en kısa zamanda bunun üzerinde çalışacağım!
BeastCoder

@Endle_Zhenbo, bir süre geçtiğini biliyorum, ama sonunda projeye bir lisans yerleştirdim.
BeastCoder

7

Saf 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 = '\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)

Yazdırılacak

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

Bunu yapmanın basit bir yolu, tüm sütunlar üzerinde döngü yapmak, genişliklerini ölçmek, o maksimum genişlik için bir row_template oluşturmak ve ardından satırları yazdırmaktır. Tam olarak aradığınız şey değil , çünkü bu durumda, başlıklarınızı masanın içine koymanız gerekiyor , ancak bunun başka biri için yararlı olabileceğini düşünüyorum.

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

Bu şekilde kullanırsınız:

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

Aşağıdaki işlev Python 3 (belki de Python 2) ile istenen tabloyu (numpy ile veya numpy olmadan) oluşturur. Her bir sütunun genişliğini en uzun takım adıyla eşleşecek şekilde ayarlamayı seçtim. Her bir sütun için ekip adının uzunluğunu kullanmak istiyorsanız değiştirebilirsiniz, ancak daha karmaşık olacaktır.

Not: yerine olabilir Python 2 doğrudan eşdeğeri için zipbirlikte izipitertools gelen.

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)

Bu aşağıdaki tabloyu üretecektir:

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

Eğer dikey çizgi ayırıcılar sahip olmak istiyorsanız, yerine " ".joinile " | ".join.

Referanslar:


2

Liste üzerinden döngü ve istediğiniz verileri temsil etmek için bir CSV biçimlendirici kullanmaya çalışacağım.

Sınırlayıcı olarak sekmeler, virgüller veya başka herhangi bir karakter belirtebilirsiniz.

Aksi takdirde, listeye göz atın ve her öğeden sonra "\ t" yazdırın

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


Bu benim ilk denememdi, muhtemelen yapılabilir, ancak biçimlendirmeyi mükemmelleştirmek için çok fazla çaba gibi görünüyor.
51'de hjweide

2

Bunu sadece basit sütunlar çıkarmanın bir yolunu buldum. Sadece sorunsuz sütunlara ihtiyacınız varsa , bunu kullanabilirsiniz:

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

EDIT: Mümkün olduğunca basit olmaya çalışıyordum ve böylece takım listesini kullanmak yerine elle bazı şeyler yaptım. OP'nin asıl sorusuna genelleme yapmak için:

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

Çıkışlardan:

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

Ama bu artık diğer cevaplardan daha basit görünmüyor, belki de daha fazla ithalat gerektirmediği için. Ancak @ campkeith'in cevabı zaten bunu karşıladı ve daha çeşitli etiket uzunluklarını işleyebileceğinden daha sağlam.


Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.