skip to Main Content

I want to find an approach to print list as tabular table. There is many library help me to do that. But when the size of list is too long, it’s not convenient to view results.

root@debian:~# print.py
name | score
-----+------
Tim  | 99
Ana  | 80
Jim  | 100
Tim  | 100
Tom  | 150
 ... long outputs ...
Lily | 100
Lucy | 120

If we can take advantage of screen width, with duplicate table on the right to reduce table length.

It’s better to print as:

name | score      name | score      name | score
-----+------      -----+------      -----+------
Tom  | 100        Jim  | 100        Tim  | 99
Ana  | 80         Lily | 99

Can any lib do that?

2

Answers


  1. Chosen as BEST ANSWER

    Resolved by the code below:

    import itertools
    import shutil
    from tabulate import tabulate
    
    
    def split(a, n):
        k, m = divmod(len(a), n)
        return (a[i * k + min(i, m):(i + 1) * k + min(i + 1, m)] for i in range(n))
    
    
    origin_data = [('Alice', 100) for _ in range(20)] + [('Bob', 99) for _ in range(20)]
    
    # get the width of terminal
    table_header = ['name', 'score']
    table_width = len((' ' * 2).join(table_header)) + 2 * len(table_header)
    table_interval = 8
    col, row = shutil.get_terminal_size() or (80, 24)
    dup_table_num = min((col + table_interval) // (table_width + table_interval), 10) or 1
    
    result = ''
    table_data = [[name, score] for name, score in origin_data]
    tabular_lines = [str(tabulate(sd, headers=table_header, stralign='right')).split('n') for sd in
                     (split(table_data, dup_table_num))]
    for line in itertools.zip_longest(*tabular_lines, fillvalue=''):
        result += (' ' * table_interval).join(line) + 'n'
    
    print(result)
    

  2. I don’t know of any libraries that do that but you can force to print in 3 columns just with indexing and formatted strings. Very ugly solution though:

    import pandas as pd
    import random
    
    names = [random.choice(['Ann', 'Bill', 'Tom']) for _ in range(900)]
    scores = [random.randint(0, 100) for _ in range(900)]
    
    df = pd.DataFrame({'name': names, 'score': scores})
    
    
    for idx in range(0, df.shape[0], 3):
        if idx == 0:
            print('name | scorett' * 3, 'n', '_____+_____tt' * 3, 'n')
        data = df.loc[idx: idx + 3, :]
        print(f'{data.name[idx]}t{data.score[idx]}tt{data.name[idx+1]}t{data.score[idx+1]}tt{data.name[idx+2]}t{data.score[idx+2]}n')
    

    And this is the output:

    name | score        name | score        name | score         
     _____+_____        _____+_____         _____+_____      
    
    Ann      71          Tom    81           Tom    8
    
    Tom      65          Tom    37           Ann    49
    
    Bill     34          Tom    81          Bill    64
    
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search