Home > other >  How to align strings in columns?
How to align strings in columns?

Time:07-07

I am trying to print out a custom format but am facing an issue.

header = ['string', 'longer string', 'str']
header1, header2, header3 = header
data = ['string', 'str', 'longest string']
data1, data2, data3 = data
len1 = len(header1)
len2 = len(header2)
len3 = len(header3)
len_1 = len(data1)
len_2 = len(data2)
len_3 = len(data3)
un = len1   len2   len3   len_1   len_2   len_3
un_c = '_' * un
print(f"{un_c}\n|{header1} |{header2} |{header3}| \n |{data1} |{data2} |{data3}|")

Output:

_____________________________________________
|string |longer string |str|
 |string |str |longest string|

The output I want is this:

_______________________________________
|string |longer string |str           |
|string |str           |longest string|

I want it to work for all lengths of strings using the len function, but I can't figure it out at all.

CodePudding user response:

There is a package called tabulate this is very good for this (https://pypi.org/project/tabulate/). Similar post here.

CodePudding user response:

Do it in two parts. First, figure out the size of each column. Then, do the printing based on those sizes.

header = ['string','longer string','str']
data = ['string','str','longest string']
lines = [header] * 3   [data] * 3

def getsizes(lines):
    maxn = [0] * len(lines[0])
    for row in lines:
        for i,col in enumerate(row):
            maxn[i] = max(maxn[i], len(col) 1)
    return maxn

def maketable(lines):
    sizes = getsizes(lines)
    all = sum(sizes)
    print('_'*(all len(sizes)) )
    for row in lines:
        print('|',end='')
        for width, col in zip( sizes, row ):
            print( col.ljust(width), end='|' )
        print()

maketable(lines)

Output:

_______________________________________
|string |longer string |str            |
|string |longer string |str            |
|string |longer string |str            |
|string |str           |longest string |
|string |str           |longest string |
|string |str           |longest string |

You could change it to build up a single string, if you need that.

CodePudding user response:

It accept an arbitrary number of rows. Supposed each row has string-type terms.

def table(*rows, padding=2, sep='|'):
    sep_middle = ' '*(padding//2)   sep   ' '*(padding//2)
    template = '{{:{}}}'

    col_sizes = [max(map(len, col)) for col in zip(*rows)]

    table_template = sep_middle.join(map(template.format, col_sizes))

    print('_' * (sum(col_sizes)   len(sep_middle)*(len(header)-1)   2*len(sep)   2*(len(sep)*padding//2)))
    for line in (header, *rows):
        print(sep   ' ' * (padding//2)   table_template.format(*line)   ' ' * (padding//2)   sep)


header = ['string', 'longer string', 'str', '21']
data1 = ['string', 'str', 'longest stringhfykhj', 'null']
data2 = ['this', 'is', 'a', 'test']

# test 1
table(header, data1, data2)

# test 2
table(header, data1, data2, padding=4, sep=':')

Output

# first test
________________________________________________________
| string | longer string | str                  | 21   |
| string | longer string | str                  | 21   |
| string | str           | longest stringhfykhj | null |
| this   | is            | a                    | test |

# second test
________________________________________________________________
:  string  :  longer string  :  str                   :  21    :
:  string  :  longer string  :  str                   :  21    :
:  string  :  str            :  longest stringhfykhj  :  null  :
:  this    :  is             :  a                     :  test  :

CodePudding user response:

Each cell is constructed according to the longest content, with additional spaces for any shortfall, printing a | at the beginning of each line, and the rest of the | is constructed using the end parameter of print

The content is placed in a nested list to facilitate looping, other ways of doing this are possible, the principle is the same and adding some content does not affect it

items = [
    ['string', 'longer string', 'str'],
    ['string', 'str', 'longest string'],
    ['longer string', 'str', 'longest string'],
]
length = [max([len(item[i]) for item in items]) for i in range(len(items[0]))]
max_length = sum(length)

print("_" * (max_length   4))
for item in items:
    print("|", end="")
    for i in range(len(length)):
        item_length = len(item[i])

        if length[i] > len(item[i]):
            print(item[i]   " " * (length[i] - item_length), end="|")
        else:
            print(item[i], end="|")
    print()

OUTPUT:

____________________________________________
|string       |longer string|str           |
|string       |str          |longest string|
|longer string|str          |longest string|
  • Related