tags:

views:

77

answers:

3

Hi all. using app engine - yes i know all about django templates and other template engines.

Lets say i have a dictionary or a simple object, i dont know its structure and i want to serialize it into html.

so if i had

{'data':{'id':1,'title':'home','address':{'street':'some road','city':'anycity','postal':'somepostal'}}}

want i want is that rendered in some form of readable html using lists or tables;

data:
   id:1
   title:home
   address:
           street: some road
           city: anycity
           postal:somepostal

now i know i can do

for key in dict.items
print dict[key]

but that wont dive into the child values and list each key, value pair when the key/value is a dictionary - ie the address dict.

Is their a module for python that is lightweight/fast that will do this nicely. or does anyone have any simple code they can paste that might do this.

Solution All the solutions here were useful. pprint is no doubt the more stable means of printing the dictionary, though it falls short of returning anything near html. Though still printable.

I ended up with this for now:

def printitems(dictObj, indent=0):
    p=[]
    p.append('<ul>\n')
    for k,v in dictObj.iteritems():
        if isinstance(v, dict):
            p.append('<li>'+ k+ ':')
            p.append(printitems(v))
            p.append('</li>')
        else:
            p.append('<li>'+ k+ ':'+ v+ '</li>')
    p.append('</ul>\n')
    return '\n'.join(p)

It converts the dict into unordered lists which is ok for now. some css and perhaps a little tweaking should make it readable.

Im going to reward the answer to the person that wrote the above code, i made a couple of small changes as the unordered lists were not nesting. I hope all agree that many of the solutions offered proved useful, But the above code renders a true html representation of a dictionary, even if crude.

+2  A: 
import pprint


pprint.pprint(yourDict)

Well, no HTML, but similar to your for/print approach.

EDIT: or use:

niceText = pprint.pformat(yourDict)

this will give you the same nice output with all indents, etc. Now you can iterate over lines and format it into HTML:

htmlLines = []
for textLine in pprint.pformat(yourDict).splitlines():
    htmlLines.append('<br/>%s' % textLine) # or something even nicer
htmlText = '\n'.join(htmlLines)
eumiro
Okay - i want to pass this to html - how do i do that - Well in honest i just want it in a string perhaps and i can pass that to html?
spidee
this dosnt work? pprint.pformat({'data': {'count': '1', 'items': {'price': '$10.99', 'id': '1001', 'title': 'keyword rental oct10'}}}) it is not returining formated data?
spidee
It returns four lines with `\n` after each line.
eumiro
Im using the code above - posted by eumiro - htmlines=[].. it builds a string with all the dict {} in and each char is on a new line? it seems the pprint.pformat just returns the dictionary back unformated?
spidee
@spidee - sorry, I forgot to `.splitlines()` the output of `pformat`. Corrected in the answer now... now it iterates over the lines
eumiro
+1  A: 

You could use pretty print (pprint)

or if you want to do some further processing of display then you have to run through the dict yourself.

Be warned that the code is crude and will require numerous refinements. Solution uses recursion too, which is bad, if the recursion depth is higher.

z = {'data':{'id':1,'title':'home','address':{'street':'some road','city':'anycity','postal':'somepostal', 'telephone':{'home':'xxx','offie':'yyy'}}}}

def printItems(dictObj, indent):
    it = dictObj.iteritems()
    for k,v in it:
        if isinstance(v, dict):
            print ' '*indent , k, ':'
            printItems(v, indent+1)
        else:
            print ' '*indent , k, ':', v

printItems(z,0)

Output:

 data :
  address :
   city : anycity
   postal : somepostal
   street : some road
   telephone :
    home : xxx
    offie : yyy
  id : 1
  title : home
pyfunc
Instead of `id str(type(v))` == "..." use `type(v) == dict` or `isinstance(v, dict)` (the latter works for subclasses too).
detly
If the address key has say telephone:{'home':'xxx','offie':'yyy'} how will it deal with that?
spidee
@spidee: I edited my answer above to include your data and it will print in the same way.
pyfunc
@detly : +1 Thanks for pointing out the crudeness in my code. It is still crude though. I rather prefer pprint
pyfunc
@spidee: While I have provided a crude answer. For your purposes eumiro has suggested pprint and is more elegant. I would suggest that you use pprint too.
pyfunc
I need to get either the above code, or pprint to make this rendable in a django template - so i need it in a string. How can i convert pprint output or above to do that?
spidee
@spidee: Mattias Nilsson has provided the answer below.
pyfunc
+2  A: 

The example made by pyfunc could easily be modified to generate simple nested html lists.

z = {'data':{'id':1,'title':'home','address':{'street':'some road','city':'anycity','postal':'somepostal'}}}

def printItems(dictObj, indent):
    print '  '*indent + '<ul>\n'
    for k,v in dictObj.iteritems():
        if isinstance(v, dict):
            print '  '*indent , '<li>', k, ':', '</li>'
            printItems(v, indent+1)
        else:
            print ' '*indent , '<li>', k, ':', v, '</li>'
    print '  '*indent + '</ul>\n'

printItems(z,0)

Not terribly pretty of course, but somewhere to start maybe. If all you want to do is visualise data, the pprint module really is good enough. You could just use the "pre" tag on the result from pprint and put that on your web page.

the pprint version would look somthing like this:

import pprint
z = {'data':{'id':1,'title':'home','address':{'street':'some road','city':'anycity','postal':'somepostal'}}}

print '<pre>', pprint.pformat(z), '</pre>'

And the html output look something like this:

{'data': {'address': {'city': 'anycity',
                      'postal': 'somepostal',
                      'street': 'some road'},
          'id': 1,
          'title': 'home'}}

Which isn't that pretty, but it at least shows the data in a more structured way.

Mattias Nilsson
@Mattias Nilsson: +1 This is much better.
pyfunc
sorry pre tag? how do i do that can you show me the code to make pprint return me an output that is in string format and can be passed to my template engine. Thank you
spidee