Reputation: 99
Assume input 'table' is a list of lists of strings, the goal is create and return a formatted
string representing the 2D table.
Here is what I got:
def show_table(table):
new_string = ''
for i in table:
for j in range(len(i)):
line = i[j]
new_string += '| {} '.format(i[j])
new_string += '|\n'
return new_string
My code works in some cases when rows' spacing is equal. For example:
input: [['A','BB'],['C','DD']]
output: '| A | BB |\n| C | DD |\n'
print:| A | BB |
| C | DD |
However, when the rows are not similar like:
input: [['10','2','300'],['4000','50','60'],['7','800','90000']]
It causes my output to differ:
Right_output: '| 10 | 2 | 300 |\n| 4000 | 50 | 60 |\n| 7 | 800 | 90000 |\n'
my_output: '| 10 | 2 | 300 |\n| 4000 | 50 | 60 |\n| 7 | 800 | 90000 |\n'
And the right output should properly looks like:
| 10 | 2 | 300 |
| 4000 | 50 | 60 |
| 7 | 800 | 90000 |
my output:
| 10 | 2 | 300 |
| 4000 | 50 | 60 |
| 7 | 800 | 90000 |
Where do I need to modifier my code to make my print out match the right output? I guess it's something about the max width of columns?
Upvotes: 2
Views: 701
Reputation: 149756
The syntax for padding a string with str.format()
(aligning to the left) is like this:
>>> '{:10}'.format('test')
'test '
You need to precalculate the widths of columns before printing the table. This produces the right output:
def show_table(table):
new_string = ''
widths = [max([len(col) for col in cols]) for cols in zip(*table)]
for i in table:
for j in range(len(i)):
new_string += '| {:{}} '.format(i[j], widths[j])
new_string += '|\n'
return new_string
Upvotes: 1
Reputation: 1233
To get your desired output, I integrated the maximum width of the table elements into your function:
def show_table(table):
max_widths = map(max, map(lambda x: map(len, x), zip(*table)))
new_string = ''
for i in table:
for j in range(len(i)):
line = i[j]
line = line + ' '*(max_widths[j]-len(line))
new_string += '| {} '.format(line)
new_string += '|\n'
return new_string
To explain the max_widths line...
max_widths = map(max, map(lambda x: map(len, x), zip(*table)))
...it could be done in 3 steps:
Transpose rows and columns of the table
transposed = zip(*table)
Get the lengths of all strings to allow comparison
lengths = map(lambda x: map(len, x), transposed)
Get the maximum length per column
max_widths = map(max, lengths)
Upvotes: 1