150 votes

Créer une belle sortie de colonne en python

J'essaie de créer une belle liste de colonnes en python pour l'utiliser avec les outils d'administration en ligne de commande que je crée.

En gros, je veux une liste comme :

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

Pour se transformer :

a            b            c
aaaaaaaaaa   b            c
a            bbbbbbbbbb   c

L'utilisation de simples tabulations ne fera pas l'affaire ici, car je ne connais pas la longueur maximale des données de chaque ligne.

C'est le même comportement que 'column -t' sous 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

J'ai cherché diverses bibliothèques python pour faire cela, mais je n'ai rien trouvé d'utile.

198voto

KurzedMetal Points 4351

Depuis Python 2.6+, vous pouvez utiliser un fichier chaîne de format de la manière suivante pour définir les colonnes à un minimum de 20 caractères et aligner le texte à droite.

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

Sortie :

               a                    b                    c
      aaaaaaaaaa                    b                    c
               a           bbbbbbbbbb                    c

143voto

Shawn Chin Points 29756
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   

Il s'agit de calculer la saisie de données la plus longue pour déterminer la largeur de la colonne, puis d'utiliser la fonction .ljust() pour ajouter le rembourrage nécessaire lors de l'impression de chaque colonne.

55voto

antak Points 2202

Je suis venu ici avec les mêmes exigences, mais les réponses de @lvc et @Preet semblent plus conformes à ce que j'attendais. column -t produit en ce que les colonnes ont des largeurs différentes :

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

23voto

Max Taggart Points 48

J'arrive un peu tard dans la soirée, et c'est une publicité éhontée pour un paquet que j'ai écrit, mais vous pouvez également consulter le site Web de la Commission européenne. Colonnaire paquet.

Il prend une liste de listes d'entrée et une liste d'en-têtes et sort une chaîne de caractères formatée en tableau. Ce snippet crée une table docker-esque :

from columnar import columnar

headers = ['name', 'id', 'host', 'notes']

data = [
    ['busybox', 'c3c37d5d-38d2-409f-8d02-600fd9d51239', 'linuxnode-1-292735', 'Test server.'],
    ['alpine-python', '6bb77855-0fda-45a9-b553-e19e1a795f1e', 'linuxnode-2-249253', 'The one that runs python.'],
    ['redis', 'afb648ba-ac97-4fb2-8953-9a5b5f39663e', 'linuxnode-3-3416918', 'For queues and stuff.'],
    ['app-server', 'b866cd0f-bf80-40c7-84e3-c40891ec68f9', 'linuxnode-4-295918', 'A popular destination.'],
    ['nginx', '76fea0f0-aa53-4911-b7e4-fae28c2e469b', 'linuxnode-5-292735', 'Traffic Cop'],
]

table = columnar(data, headers, no_borders=True)
print(table)

Table Displaying No-border Style

Ou vous pouvez être un peu plus fantaisiste avec des couleurs et des bordures. Table Displaying Spring Classics

Pour en savoir plus sur l'algorithme de dimensionnement des colonnes et voir le reste de l'API, vous pouvez consulter le lien ci-dessus ou le site Web de la Commission européenne. Repo GitHub de Columnar

9voto

Preet Kukreti Points 5058

Vous devez le faire en 2 fois :

  1. obtenir la largeur maximale de chaque colonne.
  2. formater les colonnes en utilisant notre connaissance de la largeur maximale de la première passe en utilisant str.ljust() y str.rjust()

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X