2010-10-14 33 views
5

sử dụng công cụ ứng dụng - vâng tôi biết tất cả về các mẫu django và các công cụ mẫu khác.python: tuần tự hóa từ điển thành đầu ra html đơn giản

Cho phép nói rằng tôi có từ điển hoặc một đối tượng đơn giản, tôi không biết cấu trúc của nó và tôi muốn tuần tự hóa nó thành html.

vì vậy nếu tôi đã có

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

muốn tôi muốn là kết xuất trong một số hình thức html có thể đọc được sử dụng danh sách hoặc bảng;

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

bây giờ tôi biết tôi có thể làm

for key in dict.items 
print dict[key] 

nhưng điều đó sẽ không bổ nhào vào các giá trị con và liệt kê mỗi chìa khóa, cặp giá trị khi khóa/giá trị là một cuốn từ điển - tức là dict địa chỉ.

Mô-đun của chúng cho trăn có trọng lượng nhẹ/nhanh sẽ làm điều này một cách độc đáo. hoặc bất cứ ai có bất kỳ mã đơn giản mà họ có thể dán mà có thể làm điều này.

Giải pháp Tất cả các giải pháp ở đây đều hữu ích. pprint là không có nghi ngờ các phương tiện ổn định hơn của in ấn từ điển, mặc dù nó rơi ngắn trở về bất cứ điều gì gần html. Mặc dù vẫn có thể in được.

tôi đã kết thúc với điều này cho bây giờ:

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) 

Nó chuyển đổi các dict vào danh sách không có thứ tự đó là ok cho bây giờ. một số css và có lẽ một chút tinh chỉnh nên làm cho nó dễ đọc.

Tôi sẽ trả lời câu trả lời cho người đã viết mã ở trên, tôi đã thực hiện một vài thay đổi nhỏ vì danh sách không có thứ tự không hoạt động. Tôi hy vọng tất cả đều đồng ý rằng nhiều giải pháp được cung cấp tỏ ra hữu ích, nhưng đoạn mã trên ám chỉ một biểu diễn html thực sự của từ điển, ngay cả khi thô.

+1

Không phải là một pedant, nhưng bạn không serializing từ điển của bạn, bạn in nó (với định dạng HTML). – Seth

+0

@seth vâng tôi đoán từ serialize đã bị bỏ lỡ. – spidee

Trả lời

8

Ví dụ do pyfunc dễ dàng có thể được sửa đổi để tạo danh sách html lồng nhau đơn giản.

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) 

Không hẳn là quá dễ dàng, nhưng ở đâu đó để bắt đầu có thể. Nếu tất cả những gì bạn muốn làm là trực quan hóa dữ liệu, mô-đun pprint thực sự là đủ tốt. Bạn chỉ có thể sử dụng thẻ "pre" trên kết quả từ pprint và đặt nó trên trang web của bạn.

phiên bản pprint sẽ giống như thế này:

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

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

Và sản lượng html nhìn một cái gì đó như thế này:

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

Đó là không rằng đẹp, nhưng nó ít nhất chương trình dữ liệu theo cách có cấu trúc hơn.

+0

+1 Điều này tốt hơn nhiều. – pyfunc

+0

xin lỗi thẻ trước? làm thế nào để tôi làm điều đó bạn có thể chỉ cho tôi mã để làm cho pprint trả lại cho tôi một đầu ra có định dạng chuỗi và có thể được chuyển cho công cụ mẫu của tôi. Cảm ơn bạn – spidee

4
import pprint 


pprint.pprint(yourDict) 

Vâng, không có HTML, nhưng tương tự như cách tiếp cận for/print của bạn.

EDIT: hoặc sử dụng:

niceText = pprint.pformat(yourDict) 

này sẽ cung cấp cho bạn cùng đầu ra tốt đẹp với tất cả các indents, vv Bây giờ bạn có thể lặp lại trên đường và định dạng nó vào mã HTML:

htmlLines = [] 
for textLine in pprint.pformat(yourDict).splitlines(): 
    htmlLines.append('<br/>%s' % textLine) # or something even nicer 
htmlText = '\n'.join(htmlLines) 
+0

Được rồi - tôi muốn chuyển điều này sang html - làm thế nào để tôi làm điều đó - Thật ra tôi chỉ muốn nó trong một chuỗi có lẽ và tôi có thể chuyển nó sang html? – spidee

+0

công việc dosnt này? pprint.pformat ({'data': {'count': '1', 'items': {'price': '$ 10.99', 'id': '1001', 'title': 'cho thuê từ khóa oct10'}} }) nó không phải là returining dữ liệu được hình thành? – spidee

+0

Nó trả về bốn dòng với '\ n' sau mỗi dòng. – eumiro

1

Bạn có thể sử dụng bản in đẹp (pprint)

hoặc nếu bạn muốn thực hiện thêm một số chế độ hiển thị thì bạn phải tự mình chạy qua dict.

Được cảnh báo rằng mã là thô và sẽ yêu cầu nhiều sàng lọc. Giải pháp sử dụng đệ quy quá, đó là xấu, nếu độ sâu đệ quy cao hơn.

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 
+2

Thay vì 'id str (loại (v))' == "..." sử dụng 'type (v) == dict' hoặc' isinstance (v, dict) '(sau này cũng làm việc cho các lớp con). – detly

+0

Nếu phím địa chỉ đã nói số điện thoại: {'home': 'xxx', 'offie': 'yyy'}, nó sẽ xử lý như thế nào? – spidee

+0

@spidee: Tôi đã chỉnh sửa câu trả lời ở trên để bao gồm dữ liệu của bạn và nó sẽ in theo cùng một cách. – pyfunc

2

Nhìn vào thực hiện của tôi:

def pretty_items(r, d, nametag="<strong>%s: </strong>", itemtag='<li>%s</li>', 
      valuetag="%s", blocktag=('<ul>', '</ul>')): 
if isinstance(d, dict): 
    r.append(blocktag[0]) 
    for k, v in d.iteritems(): 
     name = nametag % k 
     if isinstance(v, dict) or isinstance(v, list): 
      r.append(itemtag % name) 
      pretty_items(r, v) 
     else: 
      value = valuetag % v 
      r.append(itemtag % (name + value)) 
    r.append(blocktag[1]) 
elif isinstance(d, list): 
    r.append(blocktag[0]) 
    for i in d: 
     if isinstance(i, dict) or isinstance(i, list): 
      r.append(itemtag % " - ") 
      pretty_items(r, i) 
     else: 
      r.append(itemtag % i) 
    r.append(blocktag[1]) 

Will đầu ra tất cả các mục trong định dạng HTML sử dụng <ul><li> thẻ. Và cũng là tùy chọn để thay đổi các thẻ. Và sau đó, chỉ cần sử dụng CSS để xử lý với thụt đầu dòng.

1

Tôi cần một cái gì đó tương tự, nhưng cũng muốn danh sách in đẹp và danh sách bên trong dict. Dưới đây là những gì tôi đã đưa ra:

def format(self, obj, indent = 1): 
    if isinstance(obj, list): 
     htmls = [] 
     for k in obj: 
      htmls.append(self.format(k,indent+1)) 

     return '[<div style="margin-left: %dem">%s</div>]' % (indent, ',<br>'.join(htmls)) 

    if isinstance(obj, dict): 
     htmls = [] 
     for k,v in obj.iteritems(): 
      htmls.append("<span style='font-style: italic; color: #888'>%s</span>: %s" % (k,self.format(v,indent+1))) 

     return '{<div style="margin-left: %dem">%s</div>}' % (indent, ',<br>'.join(htmls)) 

    return str(obj) 

Sau đó, nếu bạn đang sử dụng ứng dụng web trên appengine, bạn chỉ có thể làm như sau:

self.response.out.write(self.format(obj)) 

Đây là một ví dụ về kết quả:

enter image description here

0

tưởng tượng chúng ta có điều này: {name: "a", trẻ em: [{name: "b", trẻ em: []}, {..}, {..}]

def ConvertDictToUlLi(): 
    jsonResult = GetSomeRecursiveDict() 

    def CreateHtml(DictItem, output): 
     output = "<li>"+DictItem["name"] if jsonResult.has_key("name") else " " 
     if len(DictItem["children"]) > 0: 
      output = output + "<ul>" 
      for item in DictItem["children"]: 
       output = output + " "+CreateHtml(item, output)+" " 
      output = output + "</ul>" 
     return output+"</li>" 
    result = "<ul class='tree'>"+CreateHtml(jsonResult, "")+"</ul>" 

return result 
0

Không có ví dụ nào ở trên cho kết quả tốt, vì vậy tôi đã viết hai hàm của riêng mình để tạo đầu ra html đẹp mắt cho từ điển.

def dict_to_html(dd, level=0): 
    """ 
    Convert dict to html using basic html tags 
    """ 
    import simplejson 
    text = '' 
    for k, v in dd.iteritems(): 
     text += '<br>' + '&nbsp;'*(4*level) + '<b>%s</b>: %s' % (k, dict_to_html(v, level+1) if isinstance(v, dict) else (simplejson.dumps(v) if isinstance(v, list) else v)) 
    return text 

def dict_to_html_ul(dd, level=0): 
    """ 
    Convert dict to html using ul/li tags 
    """ 
    import simplejson 
    text = '<ul>' 
    for k, v in dd.iteritems(): 
     text += '<li><b>%s</b>: %s</li>' % (k, dict_to_html_ul(v, level+1) if isinstance(v, dict) else (simplejson.dumps(v) if isinstance(v, list) else v)) 
    text += '</ul>' 
    return text 
0

Đây là phiên bản của tôi với sự hỗ trợ của danh sách (labels là những cái tên dài dòng của các phím trong từ điển):

def render_value(value, labels): 
    if isinstance(value, (list, tuple)): 
     return render_list(value, labels) 
    elif isinstance(value, dict): 
     return render_dict(value, labels) 
    else: 
     return value 


def render_list(lst, labels): 
    items = [ 
     '<li>%s</li>' % render_value(value, labels) 
     for value in lst 
    ] 
    return '\n'.join(['\n<ul>'] + items + ['</ul>\n']) 


def render_dict(dct, labels): 
    items = [] 
    for key, value in dct.items(): 
     if not value: continue 

     key = labels.get(key, key) 
     value = render_value(value, labels) 
     items.append('<li><b>%s</b>: %s</li>' % (key, value)) 

    return '\n'.join(['\n<ul>'] + items + ['</ul>\n']) 
Các vấn đề liên quan