0

I am trying to convert a list having elements in "key=value" format into a table to display to user. For this I am replacing = sign with tab and adding | at the start and at the end. This is close to what I need, but when it comes to variable length of elements, my solution breaks the formatting. something similar to column -t -s= bash comamnd is required.

import re


my_list_1=["abc=123","def=456","ghi=789","jkl=012"]
my_list_2=["abcalpha=123","def=456","ghicharlie=789","jkl=012"]

#close desired printed

for item in my_list_1:
    item_seprated=re.sub("=","\t",item)
    item_boundary=re.sub("^|$","|",item_seprated)
    print(item_boundary)

print("\n")


#undesired printed
for item in my_list_2:
    item_seprated=re.sub("=","\t",item)
    item_boundary=re.sub("^|$","|",item_seprated)
    print(item_boundary)

desired output for my_list_2:

--------------------
|key       |value  |
--------------------
|abcalpha  |    123|
|def       |    469|
|ghicharlie|    789|
|jkl       |    012|
--------------------  
monk
  • 1,953
  • 3
  • 21
  • 41

3 Answers3

2

You can use PrettyTable:

from prettytable import PrettyTable

data = ["abcalpha=123", "def=456", "ghicharlie=789", "jkl=012"]

table = PrettyTable(['key', 'value'])
table.align = 'l'
table.padding_width = 0
table.junction_char = '-'

for row in data:
    table.add_row(row.split('='))
print(table)

Results:

------------------
|key       |value|
------------------
|abcalpha  |123  |
|def       |456  |
|ghicharlie|789  |
|jkl       |012  |
------------------

Or

Write your own function:

def show_table(data, key_name='key', value_name='value'):
    max_k_len = max(map(len, (key_name, *data)))
    max_v_len = max(map(len, (value_name, *data.values())))
    horiz_sep = '-' * (max_k_len + max_v_len + 3)
    fmt = f"|{{:<{max_k_len}}}|{{:>{max_v_len}}}|".format

    print(horiz_sep)
    print(fmt(key_name, value_name))
    print(horiz_sep)
    for row in my_list_2:
        print(fmt(*row.split('=')))
    print(horiz_sep)

Then just make the list into a dict when calling it:

show_table(dict(s.split('=') for s in my_list_2))

Results:

------------------
|key       |value|
------------------
|abcalpha  |  123|
|def       |  456|
|ghicharlie|  789|
|jkl       |  012|
------------------
Jab
  • 26,853
  • 21
  • 75
  • 114
2

Without the use of any extra packages:

N1 = 0
N2 = 0

for item in my_list_2:
    item_split = item.split("=")
    N1 = max(N1, len(item_split[0]))
    N2 = max(N2, len(item_split[1]))

format = "| {:<" + str(N1) + "} | {:<" + str(N2) + "} |"
for item in my_list_2:
    item_split = item.split("=")
    print (format.format(item_split[0], item_split[1]))
b3rt0
  • 769
  • 2
  • 6
  • 21
1

Also without any dependencies, but more universal function (can handle any amount of columns):

def print_table(headers, *columns):
    if len(headers) != len(columns):
        raise ValueError()
    max_lengths = [max(max(len(item) for item in column), len(header)) for header, column in zip(headers, columns)]

    def print_row(cells):
        nonlocal max_lengths
        print("|" + "|".join(cell + " " * (max_len - len(cell)) for cell, max_len in zip(cells, max_lengths)) + "|")

    line_divider = "-" * (sum(max_lengths) + len(columns) + 1)
    print(line_divider)
    print_row(headers)
    print(line_divider)
    for row in zip(*columns):
        print_row(row)
    print(line_divider)


my_list_2=["abcalpha=123", "def=456", "ghicharlie=789", "jkl=012"]
keys, values = map(list, zip(*(s.split("=") for s in my_list_2)))

print_table(("key", "value"), keys, values)
print_table(("key", "value", "source"), keys, values, my_list_2)
Olvin Roght
  • 7,677
  • 2
  • 16
  • 35