【问题标题】:python: serialize a dictionary into a simple html outputpython:将字典序列化为简单的html输出
【发布时间】:2019-04-18 13:18:25
【问题描述】:

使用应用引擎 - 是的,我了解 django 模板和其他模板引擎。

假设我有一个字典或一个简单的对象,我不知道它的结构,我想将它序列化为 html。

如果我有的话

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

我想要的是使用列表或表格以某种形式的可读 html 呈现;

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

现在我知道我能做到

for key in dict.items
print dict[key]

但是当键/值是字典时,不会深入到子值并列出每个键、值对 - 即地址字典。

他们的python 模块是轻量级/快速的,可以很好地做到这一点。或者有没有人有任何可以粘贴的简单代码可以做到这一点。

解决方案 这里的所有解决方案都很有用。 pprint 无疑是打印字典的更稳定的方法,尽管它没有返回任何接近 html 的内容。虽然仍然可以打印。

我现在就这样结束了:

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)

它将字典转换为无序列表,目前还可以。一些 css 和一些调整应该使它可读。

我将奖励编写上述代码的人的答案,由于无序列表没有嵌套,我做了一些小改动。我希望大家都同意,提供的许多解决方案被证明是有用的,但是上面的代码呈现了字典的真实 html 表示,即使是粗略的。

【问题讨论】:

  • 不是学究,但您不是在序列化您的字典,而是在打印它(使用 HTML 格式)。
  • @seth 是的,我想 serialize 这个词被误用了。

标签: python


【解决方案1】:

pyfunc 做的例子可以很容易地修改生成简单的嵌套 html 列表。

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)

当然不是非常漂亮,但也许可以从某个地方开始。如果您只想可视化数据,pprint 模块确实足够好。您可以在 pprint 的结果上使用“pre”标签并将其放在您的网页上。

pprint 版本如下所示:

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

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

html 输出看起来像这样:

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

这不是漂亮,但它至少以更结构化的方式显示数据。

【讨论】:

  • 抱歉前置标签?我该怎么做你能告诉我让pprint返回我一个字符串格式的输出并且可以传递给我的模板引擎的代码。谢谢
【解决方案2】:
import pprint


pprint.pprint(yourDict)

嗯,没有 HTML,但类似于您的 for/print 方法。

编辑:或使用:

niceText = pprint.pformat(yourDict)

这将为您提供与所有缩进等相同的漂亮输出。现在您可以遍历行并将其格式化为 HTML:

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

【讨论】:

  • 好的 - 我想将它传递给 html - 我该怎么做 - 老实说,我可能只是想要它在一个字符串中,我可以将它传递给 html?
  • 这不起作用? pprint.pformat({'data': {'count': '1', 'items': {'price': '$10.99', 'id': '1001', 'title': '关键字租用 oct10'}} }) 它没有返回格式化数据?
  • 返回四行,每行后有\n
  • 我正在使用上面的代码 - 由 eumiro 发布 - htmlines=[].. 它构建了一个包含所有 dict {} 的字符串,并且每个字符都在新行上?似乎 pprint.pformat 只是返回未格式化的字典?
  • @spidee - 抱歉,我忘了.splitlines() pformat 的输出。现在在答案中更正......现在它迭代了这些行
【解决方案3】:

我需要类似的东西,但也想漂亮地打印列表和字典中的列表。这是我想出的:

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)

然后,如果您在 appengine 上使用 webapp,您只需执行以下操作:

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

这是一个输出示例:

【讨论】:

    【解决方案4】:

    看看我的实现:

    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])
    

    将使用&lt;ul&gt;&lt;li&gt; 标签以HTML 格式输出所有项目。并且还可以选择更改标签。然后,只需使用 CSS 处理缩进即可。

    【讨论】:

      【解决方案5】:

      上面的例子都没有给出好的结果,所以我自己写了两个函数来为字典创建漂亮的 html 输出。

      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
      

      【讨论】:

        【解决方案6】:

        这是我的简单解决方案,它可以处理任何级别的嵌套字典。

        import json
        temp_text = {'decision': {'date_time': None, 'decision_type': None},
                     'not_received': {'date_time': '2019-04-15T19:18:43.825766'},
                     'received': {'date_time': None},
                     'rfi': {'date_time': None},
                     'under_review': {'date_time': None}}
        dict_text_for_html = json.dumps(
            temp_text, indent=4
        ).replace(' ', '&nbsp').replace(',\n', ',<br>').replace('\n', '<br>')
        

        html view of python dict

        【讨论】:

          【解决方案7】:

          你可以使用漂亮的打印(pprint)

          或者如果你想对显示做一些进一步的处理,那么你必须自己运行字典。

          请注意,代码很粗糙,需要大量改进。解决方案也使用递归,如果递归深度更高,这很糟糕。

          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)
          

          输出:

           data :
            address :
             city : anycity
             postal : somepostal
             street : some road
             telephone :
              home : xxx
              offie : yyy
            id : 1
            title : home
          

          【讨论】:

          • 而不是id str(type(v)) == "..." 使用type(v) == dictisinstance(v, dict)(后者也适用于子类)。
          • 如果地址键有say phone:{'home':'xxx','offie':'yyy'} 怎么处理呢?
          • @spidee:我在上面编辑了我的答案以包含您的数据,它将以相同的方式打印。
          • @detly :+1 感谢您指出我的代码中的粗略之处。虽然它仍然很粗糙。我更喜欢 pprint
          • @spidee:虽然我提供了一个粗略的答案。出于您的目的,eumiro 建议使用 pprint 并且更优雅。我建议你也使用 pprint。
          【解决方案8】:

          这是我的支持列表的版本(labels 是字典中键的详细名称):

          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'])
          

          【讨论】:

            【解决方案9】:

            想象一下我们有这个:{name: "a", children:[{name: "b", children: [] },{..},{..}]

            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
            

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 2011-08-02
              • 1970-01-01
              • 1970-01-01
              • 2010-11-04
              • 1970-01-01
              • 1970-01-01
              • 2020-10-06
              相关资源
              最近更新 更多