Python printing tabular data

Question:

Hell All,

I have been trying to print tabular data from two dimensional list
numerical are right aligned, strings are left aligned and width of a column is dynamically decided based on max string length in each column

Example-A:

table = [['Name', 'Marks', 'Division', 'ID'], ['Raj', 7, 'A', 21], ['Shivam', 9, 'A', 52], ['Shreeya', 8, 'C', 27], ['Kartik', 5, 'B', 38]]

Name      Marks    Division  ID
----      -----    --------  --
Raj           7    A         21
Shivam        9    A         52
Shreeya       8    C         27
Kartik        5    B         38

Example-B:

table = [['Name', 'Marks', 'Div', 'Role Number'], ['Raj', 7, 'A', 21], ['Shivam', 9, 'A', 52], ['Shreeya', 8, 'C', 27], ['Kartik', 5, 'B', 38]]

Name     Marks    Div  Role Number
----     -----    ---  -----------
Raj          7    A             21
Shivam       9    A             52
Shreeya      8    C             27
Kartik       5    B             38

I could get up to determining max length of each column, but not sure how to print each row with different alignment width and that to numerical are right aligned and strings are left aligned

rlen = []
for row in table:
    clen = []
    for col in row:
        clen.append(len(str(col)))
    rlen.append(clen)
width = [max(idx) for idx in zip(*rlen)]
print(width)    #[7, 5, 8, 2]

Can someone guide please, as number of columns in input data may vary.

Asked By: Susanta Dutta

||

Answers:

You should use f-string for some (basic) formatting.

for i in table:
    print(f'{i[0]:<10} {i[1]:>10} {i[2]:<10} {i[3]:>10}')

result

Name            Marks Div        Role Number
Raj                 7 A                  21
Shivam              9 A                  52
Shreeya             8 C                  27
Kartik              5 B                  38
Answered By: Alex

You could try something like the following:

cols = []
for col in zip(*table):
    just = str.ljust if isinstance(col[1], str) else str.rjust
    strings = [str(item) for item in col]
    width = max(map(len, strings))
    cols.append(
        [strings[0].ljust(width), (len(strings[0]) * "-").ljust(width)]
        + [just(string, width) for string in strings[1:]]
    )

print("n".join("  ".join(line) for line in zip(*cols)))

The decision about the alignment is made based on the types of the 2. row.

Output for your second example

table = [['Name', 'Marks', 'Div', 'Role Number'], ['Raj', 7, 'A', 21], ['Shivam', 9, 'A', 52], ['Shreeya', 8, 'C', 27], ['Kartik', 5, 'B', 38]]

is

Name     Marks  Div  Role Number
----     -----  ---  -----------
Raj          7  A             21
Shivam       9  A             52
Shreeya      8  C             27
Kartik       5  B             38
Answered By: Timus