Crea una buena salida de columna en Python

Resuelto xeor asked hace 12 años • 22 respuestas

Estoy intentando crear una buena lista de columnas en Python para usar con las herramientas de administración de línea de comandos que creo.

Básicamente, quiero una lista como:

[['a', 'b', 'c'], ['aaaaaaaaaa', 'b', 'c'], ['a', 'bbbbbbbbbb', 'c']]

Convertirse en:

a            b            c
aaaaaaaaaa   b            c
a            bbbbbbbbbb   c

Usar pestañas simples no funcionará aquí porque no conozco los datos más largos en cada fila.

Este es el mismo comportamiento que la 'columna -t' en Linux.

$ echo -e "a b c\naaaaaaaaaa b c\na bbbbbbbbbb c"
a b c
aaaaaaaaaa b c
a bbbbbbbbbb c

$ echo -e "a b c\naaaaaaaaaa b c\na bbbbbbbbbb c" | column -t
a           b           c
aaaaaaaaaa  b           c
a           bbbbbbbbbb  c

He buscado varias bibliotecas de Python para hacer esto pero no encuentro nada útil.

xeor avatar Apr 03 '12 15:04 xeor
Aceptado

Desde Python 2.6+, puede usar una cadena de formato de la siguiente manera para establecer las columnas en un mínimo de 20 caracteres y alinear el texto a la derecha.

table_data = [
    ['a', 'b', 'c'],
    ['aaaaaaaaaa', 'b', 'c'], 
    ['a', 'bbbbbbbbbb', 'c']
]
for row in table_data:
    print("{: >20} {: >20} {: >20}".format(*row))

Producción:

               a                    b                    c
      aaaaaaaaaa                    b                    c
               a           bbbbbbbbbb                    c
KurzedMetal avatar Apr 03 '2012 15:04 KurzedMetal
data = [['a', 'b', 'c'], ['aaaaaaaaaa', 'b', 'c'], ['a', 'bbbbbbbbbb', 'c']]

col_width = max(len(word) for row in data for word in row) + 2  # padding
for row in data:
    print "".join(word.ljust(col_width) for word in row)

a            b            c            
aaaaaaaaaa   b            c            
a            bbbbbbbbbb   c   

Lo que esto hace es calcular la entrada de datos más larga para determinar el ancho de la columna y luego usarla .ljust()para agregar el relleno necesario al imprimir cada columna.

Shawn Chin avatar Apr 03 '2012 08:04 Shawn Chin

Vine aquí con los mismos requisitos, pero las respuestas de @lvc y @Preet parecen más acordes con lo que column -tproduce que las columnas tengan diferentes anchos:

>>> rows =  [   ['a',           'b',            'c',    'd']
...         ,   ['aaaaaaaaaa',  'b',            'c',    'd']
...         ,   ['a',           'bbbbbbbbbb',   'c',    'd']
...         ]
...

>>> widths = [max(map(len, col)) for col in zip(*rows)]
>>> for row in rows:
...     print "  ".join((val.ljust(width) for val, width in zip(row, widths)))
...
a           b           c  d
aaaaaaaaaa  b           c  d
a           bbbbbbbbbb  c  d
antak avatar Aug 22 '2012 02:08 antak