Building a table with the data from scratch Python

You're nearly there. You could divide the task into smaller portions and use join() to make your life easier.

Let's first define some constant characters to improve code readability

char_line = u'\u2500'
char_lcorner_top = u'\u250C'
char_rcorner_top = u'\u2510'
char_lside = u'\u251C'
char_rside = u'\u2524'
char_top = u'\u252C'
char_bot = u'\u2534'
char_cross = u'\u253C'
char_lcorner_bot = u'\u2514'
char_rcorner_bot = u'\u2518'

Now let's write functions to create the lines between rows:

def top_rule(width, ncols):
    return char_lcorner_top + char_top.join([char_line * width for i in range(ncols)]) + char_rcorner_top

Explanation:

  • char_line * width multiplies the - character width times. Let's say width = 4. This would give four dashes like so: ----
  • [char_line * width for i in range(ncols)] creates a list with ncols items, each of which is ----.
  • char_top.join(...) joins the elements of the list with the character
  • Before returning, we add before and after the string we just created.

So top_rule(4, 3) gives "┌────┬────┬────┐"

Similarly, we can define more functions:

def bot_rule(width, ncols):
    return char_lcorner_bot + char_bot.join([char_line * width for i in range(ncols)]) + char_rcorner_bot

def mid_rule(width, ncols):
    return char_lside + char_cross.join([char_line * width for i in range(ncols)]) + char_rside

In each row, we have multiple cells to format. Let's write a function to format each row individually.

def fmt_row(row, width, loffset):
    return "|" + "|".join([cell.ljust(width - loffset).rjust(width) for cell in row]) + "|"

For each cell in the row, we left-justify the cell text to a length of (width - loffset) and right-justify it to width. Then, join with a pipe (|) and add pipes before and after

Now all we need to do is call the functions we made. Remember we only need to print a single mid_rule after all rows except the last. After the last row, we need to print a bot_rule.

num_cols = len(data[0])
length_list = [len(element) for row in data for element in row]
column_width = max(length_list) + 2

print(top_rule(column_width, num_cols))
for row in data[:-1]:
    print(fmt_row(row, column_width, 1))
    print(mid_rule(column_width, num_cols))

print(fmt_row(data[-1], column_width, 1))
print(bot_rule(column_width, num_cols))

With your data, you should get this:

┌────────┬────────┬────────┐
| ID     | Name   | Age    |
├────────┼────────┼────────┤
| 1      | John   | 35     |
├────────┼────────┼────────┤
| 2      | Joseph | 40     |
└────────┴────────┴────────┘

Tags:

Python