0

I tried to find the answer but most of the answers use advance functions like map() or zip(). I have to use only string attributes, methods or functions. I could not find answer with string functions or attributes.

I need to print a given lists of list into a right justified columns. Its a kind of transpose of each sub list i.e. the first list in the lists of list is printed as fist column of the table, the second list second column and so on.

The given lists of lists:

tableData = [['apples', 'oranges', 'cherries', 'banana'],
             ['Alice', 'Bob', 'Carol', 'David'],
             ['dogs', 'cats', 'moose', 'goose']]

and the desired output:

enter image description here

Note that the argument to rjust() comes from the max length of the longest word in the tableData.

I have figured out the max integer length of the longest word in tableData as follows:

colWidths=[]
for i in range(len(tableData)):
    maxL=len(max(tableData[i], key=len))
    colWidths.append(maxL) 
max(colWidths)

Now I am stuck how to write a loop to print the lists in required table format. (I could do it using zip() or map() but thats not accepted!) Any help?

Moh
  • 61
  • 6

2 Answers2

1

If you don't want to transpose table, you can do it dirty way:

for column in range(4):
    for row in range(3):
        print(tableData[row][column].rjust(10), end='')
    print('')

Column/row range can be set dynamically, if your task needs it

Slam
  • 8,112
  • 1
  • 36
  • 44
  • What if there are 10 *sub*-lists with 6 items each? what if you don't know how many *sub*-lists there are or how many items they contain/ – wwii Jan 08 '19 at 22:41
  • Perfect, i updated to make it dynamic for cols, rows and rjust() argument as well. Thanks :) – Moh Jan 08 '19 at 22:49
0

A one liner to get that max length:

max_len = max(map(max, [map(len, l) for l in tableData]))

But if you're prevented from using map somehow, this is still simpler:

max_len = 0
for l in tableData:
    for s in l:
        max_len = max(max_len, len(s))

And to print the table, the main issue is that the table needs to be transposed first:

printTableData = list(map(list, zip(*tableData)))

Again, without map or zip, it's more work:

max_col_len = 0
for l in tableData:
    max_col_len = max(max_col_len, len(l))
printTableData2 = [[] for _ in range(max_col_len)]
for i in range(max_col_len):
    for j in range(len(tableData)):
        if i <= len(tableData[j]):
            printTableData2[i].append(tableData[j][i])
        else:
            printTableData2[i].append('')

And to print the whole thing:

for l in printTableData:
    for s in l:
        sys.stdout.write(s.rjust(max_len+1))
    sys.stdout.write('\n')

Note that that's not exactly what you need, since the image you provided has every column right adjusted separately. So, as a full solution:

import sys

tableData = [['apples', 'oranges', 'cherries', 'banana'],
             ['Alice', 'Bob', 'Carol', 'David'],
             ['dogs', 'cats', 'moose', 'goose']]

max_lens = []
max_col_len = 0
for l in tableData:
    max_col_len = max(max_col_len, len(l))
    max_len = 0
    for s in l:
        max_len = max(max_len, len(s))
    max_lens.append(max_len)

printTableData = [[] for _ in range(max_col_len)]
for i in range(max_col_len):
    for j in range(len(tableData)):
        if i <= len(tableData[j]):
            printTableData[i].append(tableData[j][i])
        else:
            printTableData[i].append('')

for l in printTableData:
    for i in range(len(l)):
        sys.stdout.write(l[i].rjust(max_lens[i]+1))
    sys.stdout.write('\n')

I'm not sure trying to solve problems without using what the language provides you (like map and zip) is a good idea - unless someone is trying to teach you a lesson on their usefulness or on how to write loops. But then, you probably shouldn't be asking here...

Grismar
  • 27,561
  • 4
  • 31
  • 54
  • Hi, thanks for the detailed solution. I guess its just to know the value of functions later on ;) – Moh Jan 08 '19 at 23:11