Python - Printing a dictionary as a horizontal table with headers

前端 未结 6 546
花落未央
花落未央 2020-12-02 19:01

I have a dictionary:

import math
import random

d = {1: ["Spices", math.floor(random.gauss(40, 5))],
    2: ["Other stuff", math.floor(ran         


        
相关标签:
6条回答
  • 2020-12-02 19:08

    I would prefer pandas DataFrame

    import pandas as pd
    data = {'Name': ['a', 'b', 'c'], 'Age': [10, 11, 12]}
    df = pd.DataFrame(data)
    print(df)
    

    Output:

      Name  Age
    0    a   10
    1    b   11
    2    c   12
    

    check out more about printing pretty a dataframe here

    0 讨论(0)
  • 2020-12-02 19:20

    I was looking for a solution with unknown columns width to print a database table. So here it is:

    def printTable(myDict, colList=None):
       """ Pretty print a list of dictionaries (myDict) as a dynamically sized table.
       If column names (colList) aren't specified, they will show in random order.
       Author: Thierry Husson - Use it as you want but don't blame me.
       """
       if not colList: colList = list(myDict[0].keys() if myDict else [])
       myList = [colList] # 1st row = header
       for item in myDict: myList.append([str(item[col] if item[col] is not None else '') for col in colList])
       colSize = [max(map(len,col)) for col in zip(*myList)]
       formatStr = ' | '.join(["{{:<{}}}".format(i) for i in colSize])
       myList.insert(1, ['-' * i for i in colSize]) # Seperating line
       for item in myList: print(formatStr.format(*item))
    

    Sample:

    printTable([{'a':123,'bigtitle':456,'c':789},{'a':'x','bigtitle':'y','c':'z'}, \
        {'a':'2016-11-02','bigtitle':1.2,'c':78912313213123}], ['a','bigtitle','c'])
    

    Output:

    a          | bigtitle | c             
    ---------- | -------- | --------------
    123        | 456      | 789           
    x          | y        | z             
    2016-11-02 | 1.2      | 78912313213123
    

    In Psycopg context, you can use it this way:

    curPG.execute("SELECT field1, field2, ... fieldx FROM mytable")
    printTable(curPG.fetchall(), [c.name for c in curPG.description])
    

    If you need a variant for multi-lines rows, here it is:

    def printTable(myDict, colList=None, sep='\uFFFA'):
       """ Pretty print a list of dictionaries (myDict) as a dynamically sized table.
       If column names (colList) aren't specified, they will show in random order.
       sep: row separator. Ex: sep='\n' on Linux. Default: dummy to not split line.
       Author: Thierry Husson - Use it as you want but don't blame me.
       """
       if not colList: colList = list(myDict[0].keys() if myDict else [])
       myList = [colList] # 1st row = header
       for item in myDict: myList.append([str(item[col] or '') for col in colList])
       colSize = [max(map(len,(sep.join(col)).split(sep))) for col in zip(*myList)]
       formatStr = ' | '.join(["{{:<{}}}".format(i) for i in colSize])
       line = formatStr.replace(' | ','-+-').format(*['-' * i for i in colSize])
       item=myList.pop(0); lineDone=False
       while myList:
          if all(not i for i in item):
             item=myList.pop(0)
             if line and (sep!='\uFFFA' or not lineDone): print(line); lineDone=True
          row = [i.split(sep,1) for i in item]
          print(formatStr.format(*[i[0] for i in row]))
          item = [i[1] if len(i)>1 else '' for i in row]
    

    Sample:

    sampleDict = [{'multi lines title': 12, 'bigtitle': 456, 'third column': '7 8 9'},
    {'multi lines title': 'w x y z', 'bigtitle': 'b1 b2', 'third column': 'z y x'},
    {'multi lines title': '2', 'bigtitle': 1.2, 'third column': 78912313213123}]
    
    printTable(sampleDict, sep=' ')
    

    Output:

    bigtitle | multi | third         
             | lines | column        
             | title |               
    ---------+-------+---------------
    456      | 12    | 7             
             |       | 8             
             |       | 9             
    ---------+-------+---------------
    b1       | w     | z             
    b2       | x     | y             
             | y     | x             
             | z     |               
    ---------+-------+---------------
    1.2      | 2     | 78912313213123
    

    Without sep parameter, printTable(sampleDict) gives you:

    bigtitle | multi lines title | third column  
    ---------+-------------------+---------------
    456      | 12                | 7 8 9         
    b1 b2    | w x y z           | z y x         
    1.2      | 2                 | 78912313213123
    
    0 讨论(0)
  • 2020-12-02 19:22

    You can use ljust or rjust string methods:

    print key.ljust(10), label.ljust(30), number.ljust(20)
    
    0 讨论(0)
  • 2020-12-02 19:25

    Based on Le Droid's code, I added separator '-' for each row which could make the print more clear. Thanks, Le Droid.

    def printTable(myDict, colList=None):
        if not colList: 
            colList = list(myDict[0].keys() if myDict else [])
        myList = [colList] # 1st row = header
        for item in myDict: 
            myList.append([str(item[col] or '') for col in colList])
        #maximun size of the col for each element
        colSize = [max(map(len,col)) for col in zip(*myList)]
        #insert seperating line before every line, and extra one for ending. 
        for i in  range(0, len(myList)+1)[::-1]:
             myList.insert(i, ['-' * i for i in colSize])
        #two format for each content line and each seperating line
        formatStr = ' | '.join(["{{:<{}}}".format(i) for i in colSize])
        formatSep = '-+-'.join(["{{:<{}}}".format(i) for i in colSize])
        for item in myList: 
            if item[0][0] == '-':
                print(formatSep.format(*item))
            else:
                print(formatStr.format(*item))
    

    Output:

    -----------+----------+---------------
    a          | bigtitle | c             
    -----------+----------+---------------
    123        | 456      | 789           
    -----------+----------+---------------
    x          | y        | z             
    -----------+----------+---------------
    2016-11-02 | 1.2      | 78912313213123
    -----------+----------+---------------
    
    0 讨论(0)
  • 2020-12-02 19:29

    String formatting provides a nice, simple solution. This answer is an update for Python 3 of the nice answer from @Ashwini.

    str_fmt = "{:<8} {:<15} {:<10}"
    print(str_fmt.format('Key','Label','Number'))
    for k, v in d.items():
        label, num = v
        print(str_fmt.format(k, label, num))
    
    0 讨论(0)
  • 2020-12-02 19:31

    You can use string formatting:

    print "{:<8} {:<15} {:<10}".format('Key','Label','Number')
    for k, v in d.iteritems():
        label, num = v
        print "{:<8} {:<15} {:<10}".format(k, label, num)
    

    Output:

    Key      Label           Number    
    1        Spices          38.0      
    2        Other stuff     24.0      
    3        Tea             44.0      
    5        Fruit           5.0       
    6        Textiles        37.0      
    10       Contraband      1000.0 
    
    0 讨论(0)
提交回复
热议问题