Lijsten afdrukken als gegevens in tabelvorm

Ik ben vrij nieuw voor Python en ik worstel nu met het netjes opmaken van mijn gegevens voor afgedrukte uitvoer.

Ik heb één lijst die wordt gebruikt voor twee koppen, en een matrix die de inhoud van de tabel zou moeten zijn. Vind ik leuk:

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

Houd er rekening mee dat de kopnamen niet noodzakelijk even lang zijn. De gegevensinvoer zijn echter allemaal gehele getallen.

Nu wil ik dit in een tabelformaat weergeven, ongeveer als volgt:

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

Ik heb het idee dat hier een datastructuur voor moet zijn, maar ik kan het niet vinden. Ik heb geprobeerd een woordenboek te gebruiken en het afdrukken te formatteren, ik heb for-loops met inspringing geprobeerd en ik heb geprobeerd als strings af te drukken.

Ik weet zeker dat er een heel eenvoudige manier moet zijn om dit te doen, maar ik mis het waarschijnlijk door gebrek aan ervaring.


Antwoord 1, autoriteit 100%

Enkele ad-hoccode:

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

Dit is afhankelijk van str.format()en de Formaatspecificatie Mini-Taal.


Antwoord 2, autoriteit 98%

Er zijn enkele lichte en handige pythonpakketten voor dit doel:

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

tabulate heeft veel opties om kopteksten en tabelopmaak te specificeren.

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 heeft opties om gegevens uit csv-, html- en sql-databases te lezen. U kunt ook een subset van gegevens selecteren, de tabel sorteren en tabelstijlen wijzigen.

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

met teksttabel kunt u de horizontale/verticale uitlijning, randstijl en gegevenstypen regelen.

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

met teksttabel kunt u de horizontale/verticale uitlijning, randstijl en gegevenstypen regelen.

Andere opties:

  • terminaltablesTeken eenvoudig tabellen in terminal-/console-applicaties uit een lijst met lijsten met strings. Ondersteunt rijen met meerdere regels.
  • asciitableAsciitable kan een breed scala aan ASCII-tabelindelingen lezen en schrijven via ingebouwde Extension Reader-klassen.

Antwoord 3, autoriteit 38%

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

Antwoord 4, autoriteit 31%

Python maakt dit eigenlijk vrij eenvoudig.

Zoiets als

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

zal de output hebben

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

Het % in de string is in wezen een escape-teken en de tekens die erop volgen vertellen python wat voor soort formaat de gegevens zouden moeten hebben. Het % buiten en na de tekenreeks vertelt python dat u van plan bent de vorige tekenreeks als formaattekenreeks te gebruiken en dat de volgende gegevens in het opgegeven formaat moeten worden geplaatst.

In dit geval heb ik “%-12i” twee keer gebruikt. Elk deel opsplitsen:

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

Uit de documenten: https://docs.python.org/ 2/library/stdtypes.html#string-formatting


Antwoord 5, autoriteit 12%

Het antwoord van Sven Marnach bijwerken om in Python 3.4 te werken:

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

Antwoord 6, autoriteit 8%

Ik weet dat ik te laat op het feest ben, maar ik heb hier zojuist een bibliotheek voor gemaakt waarvan ik denk dat het echt kan helpen. Het is extreem eenvoudig, daarom denk ik dat je het moet gebruiken. Het heet TableIT.

Basisgebruik

Om het te gebruiken, volg je eerst de download-instructies op de GitHub-pagina.

Importeer het dan:

import TableIt

Maak vervolgens een lijst met lijsten waarbij elke binnenste lijst een rij is:

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

Dan hoef je het alleen nog maar af te drukken:

TableIt.printTable(table)

Dit is de output die je krijgt:

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

Veldnamen

Je kunt veldnamen gebruiken als je dat wilt (als je geen veldnamen gebruikt, hoef je useFieldNames=False niet te zeggen omdat het standaard zo is ingesteld):


TableIt.printTable(table, useFieldNames=True)

Daarvan krijg je:

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

Er zijn andere toepassingen om bijvoorbeeld dit te doen:

import TableIt
myList = [
    ["Name", "Email"],
    ["Richard", "[email protected]"],
    ["Tasha", "[email protected]"]
]
TableIt.print(myList, useFieldNames=True)

Daaruit:

+-----------------------------------------------+
| Name                  | Email                 |
+-----------------------+-----------------------+
| Richard               | [email protected] |
| Tasha                 | [email protected]    |
+-----------------------------------------------+

Of je zou kunnen doen:

import TableIt
myList = [
    ["", "a", "b"],
    ["x", "a + x", "a + b"],
    ["z", "a + z", "z + b"]
]
TableIt.printTable(myList, useFieldNames=True)

En daaruit krijg je:

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

Kleuren

Je kunt ook kleuren gebruiken.

Je gebruikt kleuren door de kleuroptie te gebruiken (standaard is deze ingesteld op Geen) en RGB-waarden op te geven.

Gebruik het bovenstaande voorbeeld:

import TableIt
myList = [
    ["", "a", "b"],
    ["x", "a + x", "a + b"],
    ["z", "a + z", "z + b"]
]
TableIt.printTable(myList, useFieldNames=True, color=(26, 156, 171))

Dan krijg je:

Houd er rekening mee dat het afdrukken van kleuren misschien niet voor u werkt, maar het werkt precies hetzelfde als de andere bibliotheken die gekleurde tekst afdrukken. Ik heb getest en elke kleur werkt. Het blauw is ook niet in de war zoals het zou zijn als je de standaard 34mANSI-escape-reeks gebruikt (als je niet weet wat dat is, maakt het niet uit). Hoe dan ook, het komt allemaal voort uit het feit dat elke kleur een RGB-waarde is in plaats van een systeemstandaard.

Meer informatie

Ga voor meer informatie naar de GitHub-pagina


Antwoord 7, autoriteit 4%

Als ik dit doe, heb ik graag wat controle over de details van de opmaak van de tabel. Ik wil met name dat koptekstcellen een ander formaat hebben dan lichaamscellen, en dat de kolombreedten van de tabel niet zo breed zijn als nodig is. Hier is mijn oplossing:

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

Dit is de uitvoer:

                  | 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

Antwoord 8, autoriteit 4%

Een eenvoudige manier om dit te doen is door alle kolommen te doorlopen, hun breedte te meten, een row_template voor die maximale breedte te maken en vervolgens de rijen af te drukken. Het is niet precies wat u zoekt, omdat u in dit geval eerst uw koppen inin de tabel moet zetten, maar ik denk dat het nuttig kan zijn voor iemand anders.

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

Je gebruikt het als volgt:

>>> print_table(table)
            Man Utd   Man City   T Hotspur
  Man Utd         1          0           0
 Man City         1          1           0
T Hotspur         0          1           2

Antwoord 9, autoriteit 3%

Ik denk dat ditis wat je zoekt voor.

Het is een eenvoudige module die alleen de maximaal vereiste breedte voor de tabelinvoer berekent en vervolgens gewoon rjusten ljustom een mooie afdruk van de gegevens te maken.

Als u uw linkerkop rechts uitgelijnd wilt hebben, wijzigt u deze oproep:

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

Van regel 53 met:

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

Antwoord 10, autoriteit 3%

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

Wordt afgedrukt

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

Antwoord 11, Autoriteit 3%

Gebruik het gewoon

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)

Als gevolg hiervan krijg je zo’n nette tafel en dat is het.


Antwoord 12

De volgende functie maakt de gevraagde tabel (met of zonder Numpy) met Python 3 (misschien ook Python 2). Ik heb ervoor gekozen om de breedte van elke kolom in te stellen die overeenkomt met die van de langste teamnaam. U kunt het wijzigen als u de lengte van de teamnaam voor elke kolom wilde gebruiken, maar zal ingewikkelder zijn.

Opmerking: voor een directe equivalent in Python 2 kunt u de zipvervangen door izipvan 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)

Hiermee produceert u de volgende tabel:

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

Als u verticale lijnafscheiders wilt hebben, kunt u " ".joinmet " | ".join.

Referenties:


Antwoord 13

Ik zou proberen de lijst door te lopen en een CSV-formatter te gebruiken om de gewenste gegevens weer te geven.

U kunt tabbladen, komma’s of een andere char als de scheidingsteken opgeven.

Anders loopt u gewoon door de lijst en druk “\ t” na elk element

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


Antwoord 14

Ik vond dit gewoon op zoek naar een manier om eenvoudige kolommen uit te voeren. Als u alleen NO-FUSS Columns nodig hebt , kunt u dit gebruiken:

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

EDIT: ik probeerde zo eenvoudig mogelijk te zijn en deed daardoor sommige dingen handmatig in plaats van de teamslijst te gebruiken. Om te generaliseren naar de eigenlijke vraag van de 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()

Uitgangen:

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

Maar dit lijkt niet langer eenvoudiger dan de andere antwoorden, met misschien als voordeel dat er geen invoer meer nodig is. Maar het antwoord van @campkeith voldeed daar al aan en is robuuster omdat het een grotere verscheidenheid aan labellengtes aankan.


Antwoord 15

Voor eenvoudige gevallen kunt u gewoon moderne tekenreeksopmaak gebruiken (vereenvoudigd antwoord van 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]}')

Uitvoer:

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

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


Antwoord 16

Een eenvoudige tabel maken met behulp van terminaltables

Open de terminal of uw opdrachtprompt en voer pip install terminaltablesuit
U kunt de lijst als volgt afdrukken en pythonen

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)

Ze hebben andere coole tafels, vergeet ze niet te bekijken. Google gewoon hun bibliotheek.

Hopelijk helpt dat :100:!


Antwoord 17

Ik heb een betere die veel ruimte kan besparen.

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

uitvoer:

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

Other episodes