2011-12-02 15 views
24

Używając python2.7, próbuję wydrukować dane tabelaryczne.Wydruk tabelaryczny w formacie Python

To jest mniej więcej to, co mój kod wygląda następująco:

for i in mylist: 
    print "{}\t|{}\t|".format (i, f(i)) 

Problem polega na tym, że w zależności od długości i lub f(i) dane nie zostaną wyrównane.

To co mi chodzi:

|foo |bar | 
|foobo |foobar | 

Co chcę uzyskać:

|foo  |bar  | 
|foobo |foobar | 

Czy są jakieś moduły, które pozwalają to zrobić?

Odpowiedz

24

To naprawdę nie jest trudne, aby rzucić swoją funkcję formatowania:

def print_table(table): 
    col_width = [max(len(x) for x in col) for col in zip(*table)] 
    for line in table: 
     print "| " + " | ".join("{:{}}".format(x, col_width[i]) 
           for i, x in enumerate(line)) + " |" 

table = [(str(x), str(f(x))) for x in mylist] 
print_table(table) 
+3

Dla porównania innych, musiałem zmienić ciąg formatu na «{0: {1}}», aby zmusić go do poprawnej pracy. – Darkhydro

+0

Pylint narzeka na * :(. Mówi "Użyta * lub ** magia". –

+5

Zauważ, że ten kod może nie działać poprawnie, jeśli iterables w tabeli zawierają jakiekolwiek obiekty nie będące ciągami, ponieważ len albo nie będzie zdefiniowany, lub może być niepoprawny Aby to zmienić, zmień 'max (len (x)' na 'max (len (str (x))'. –

7
mylist = {"foo":"bar", "foobo":"foobar"} 

width_col1 = max([len(x) for x in mylist.keys()]) 
width_col2 = max([len(x) for x in mylist.values()]) 

def f(ind): 
    return mylist[ind] 

for i in mylist: 
    print "|{0:<{col1}}|{1:<{col2}}|".format(i,f(i),col1=width_col1, 
              col2=width_col2) 
+2

Działa dzięki. Ale jestem zaskoczony, że nie ma modułu, który mógłby to zrobić natywnie! – rahmu

16

Dla bardziej pięknego tabeli użyć modułu tabularyzować:

Tabulate link

Tutaj zgłoszoną przykład:

>>> from tabulate import tabulate 

>>> table = [["Sun",696000,1989100000],["Earth",6371,5973.6], 
...   ["Moon",1737,73.5],["Mars",3390,641.85]] 
>>> print tabulate(table) 
----- ------ ------------- 
Sun 696000  1.9891e+09 
Earth 6371 5973.6 
Moon  1737 73.5 
Mars  3390 641.85 
----- ------ ------------- 
+0

Tak, użyłem tego i bardzo proste jest mieć strukturę przypominającą stół w zaledwie kilku liniach kodu! –

4

Wydaje się, że chcesz, aby kolumny lewej uzasadnione, ale nie widziałem żadnych odpowiedzi wspomnieć metodę ljust ciąg, więc będę wykazać, że w Pythonie 2.7:

def bar(item): 
    return item.replace('foo','bar') 

width = 20 
mylist = ['foo1','foo200000','foo33','foo444'] 

for item in mylist: 
    print "{}| {}".format(item.ljust(width),bar(item).ljust(width)) 

foo1    | bar1 
foo200000   | bar200000 
foo33    | bar33 
foo444    | bar444 

celach informacyjnych, prowadzenie help('abc'.ljust) daje to:

S.ljust (szerokość [, fillchar]) -> ciąg

wygląda na to metoda ljust ma swoje określona szerokość i odejmuje długość łańcucha od tej wartości, i umieszcza prawą stronę łańcucha z taką liczbą znaków.

3

Możesz spróbować BeautifulTable. Oto przykład:

>>> 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 | 
+----------+------+--------+ 
Powiązane problemy