Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Python - Printing a dictionary as a horizontal table with headers

I have a dictionary:

import math import random  d = {1: ["Spices", math.floor(random.gauss(40, 5))],     2: ["Other stuff", math.floor(random.gauss(20, 5))],     3: ["Tea", math.floor(random.gauss(50, 5))],     10: ["Contraband", math.floor(random.gauss(1000, 5))],     5: ["Fruit", math.floor(random.gauss(10, 5))],     6: ["Textiles", math.floor(random.gauss(40, 5))] } 

I want to print it out so it lines up nicely with headers. Can I add the headers to the dictionary and always be sure they come out on top? I've seen a few ways to do it vertically but I'd like to have it come out with max column widths close to the max str() or int().

Example:

Key___________________Label______________________Number
1______________________Spices_____________________42
2______________________Other Stuff_____________16
etc

Apparently I can't even do this inside of this editor manually, but I hope the idea comes across. I also don't really want the __ either. Just a place holder.
Thanks all.

like image 433
Faller Avatar asked Jun 26 '13 20:06

Faller


People also ask

How do I print a dictionary neatly in Python?

Use pprint() to Pretty Print a Dictionary in Python Within the pprint module there is a function with the same name pprint() , which is the function used to pretty-print the given string or object. First, declare an array of dictionaries. Afterward, pretty print it using the function pprint.

How do I print a dictionary without the curly braces?

You can use slicing on the string representation of a dictionary to access all characters except the first and last ones—that are the curly bracket characters. For example, the expression print(str({'a': 1, 'b': 2})[1:-1]) prints the list as 'a': 1, 'b': 2 without enclosing brackets.


2 Answers

You can use string formatting in python2:

    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) 

Or, string formatting in python3:

    print("{:<8} {:<15} {:<10}".format('Key','Label','Number'))     for k, v in d.items():         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  
like image 126
Ashwini Chaudhary Avatar answered Sep 23 '22 21:09

Ashwini Chaudhary


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 or any(item):       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 
like image 40
Le Droid Avatar answered Sep 24 '22 21:09

Le Droid