迭代嵌套字典并生成HTML的代码

2024-05-16 01:07:24 发布

您现在位置:Python中文网/ 问答频道 /正文

我发现并修改了一些代码,这些代码在嵌套字典中进行迭代,并生成列出嵌套字典中所有键和值的HTML。代码还行,但有几点我想改进:

  1. 现有的代码依赖于一个全局变量,我认为这不是一个好的实践
  2. 代码会重复每个字段的完整路径,该路径有点长:
<li>employees.1.forename.'Jack'</li>
<li>employees.1.surname.'Smith'</li>
<li>employees.1.address.AddressLine1.'59 Never Street'</li>
<li>employees.1.address.AddressLine2.'Flat 10'</li>
<li>employees.1.address.PostTown.'London'</li>
<li>employees.1.address.Postcode.'E1 1AB'</li>
<li>employees.2.forename.'Kate'</li>
<li>employees.2.surname.'Jones'</li>
<li>employees.2.address.AddressLine1.'29 Acacia Avenue'</li><li>employees.2.address.AddressLine2.None</li>
<li>employees.2.address.PostTown.'London'</li>
<li>employees.2.address.Postcode.'N10 2BC'</li>

理想情况下,字段将以更可读的嵌套格式列出,如下所示:

<ul>
    <li>employees:</li>
        <ul>
            <li>1:</li>
            <ul>
                <li>forename:'Jack'</li>
                <li>surname: 'Smith'</li>
                <li>address:
                <ul>
                    <li>AddressLine1:'59 Never Street'</li>
                    <li>AddressLine2:'Flat 10'</li>
                    <li>PostTown: 'London'</li>
                    <li>Postcode:'E10 1AB'</li> 
                </ul>
            </ul>
        </ul>
        <ul>
            <li>1:</li>
            <ul>
                <li>forename:'Kate'</li>
                <li>surname: 'Jones'</li>
                <li>address:
                <ul>
                    <li>AddressLine1:'29 Acacia Avenue'</li>
                    <li>AddressLine2: None</li>
                    <li>PostTown: 'London'</li>
                    <li>Postcode:'N10 2BC'</li> 
                </ul>
            </ul>
        </ul>
</ul>

d = {
        'employees':
            {
            '1':
                {
                'forename': 'Jack',
                'surname': 'Smith',
                'address':
                    {
                    'AddressLine1': '59 Never Street',
                    'AddressLine2': 'Flat 10',
                    'PostTown': 'London',
                    'Postcode': 'E1 1AB'
                    }
                },
            '2':
                {
                'forename': 'Kate',
                'surname': 'Jones',
                'address':
                    {
                    'AddressLine1': '29 Acacia Avenue',
                    'AddressLine2': None,
                    'PostTown': 'London',
                    'Postcode': 'N10 2BC'
                    }
                }
            }
        }

def print_dict(v, prefix='<li>'):
        global out
        if isinstance(v, dict):
                for k, v2 in v.items():
                        p2 = "{}{}.".format(prefix, k)
                        print_dict(v2, p2)
        else:
                try: out = str(out) + prefix + repr(v) + '</li>'
                except: out = prefix + repr(v) + '</li>'
        return out

print(print_dict(d))

Tags: 代码prefixaddresslisurnameoutuldict
1条回答
网友
1楼 · 发布于 2024-05-16 01:07:24

获得所需输出的一个可能解决方案是使用yattag

>>> from yattag import Doc
>>> doc, tag, text = Doc().tagtext()
>>> d = { ... }
>>> 
>>> def f(d, tag, text):
...  with tag('ul'):
...   for k,v in d.items():
...     if type(v) == dict:
...      with tag('li'):
...       text(k)
...      f(v, tag, text)
...     else:
...      with tag('li'):
...       text(f"{k}: '{v}'")
... 
>>> f(d, tag, text)
>>> 
>>> doc.getvalue()
"<ul><li>employees</li><ul><li>1</li><ul><li>forename: 'Jack'</li><li>surname: 'Smith'</li><li>address</li><ul><li>AddressLine1: '59 Never Street'</li><li>AddressLine2: 'Flat 10'</li><li>PostTown: 'London'</li><li>Postcode: 'E1 1AB'</li></ul></ul><li>2</li><ul><li>forename: 'Kate'</li><li>surname: 'Jones'</li><li>address</li><ul><li>AddressLine1: '29 Acacia Avenue'</li><li>AddressLine2: 'None'</li><li>PostTown: 'London'</li><li>Postcode: 'N10 2BC'</li></ul></ul></ul></ul>"

它还显示了如何摆脱使用global关键字-将变量作为参数传递给函数

另一种选择是使用类

如果不想使用外部库,请执行以下操作:

>>> def f(d):
...  result = ['<ul>']
...  for k,v in d.items():
...   if type(v) == dict:
...    result.append(f'<li>{k}</li>')
...    result.extend(f(v))
...   else:
...    result.append(f"<li>{k}: '{v}'</li>")
...  result.append('</ul>')
...  return result
... 
>>> ''.join(f(d))
"<ul><li>employees</li><ul><li>1</li><ul><li>forename: 'Jack'</li><li>surname: 'Smith'</li><li>address</li><ul><li>AddressLine1: '59 Never Street'</li><li>AddressLine2: 'Flat 10'</li><li>PostTown: 'London'</li><li>Postcode: 'E1 1AB'</li></ul></ul><li>2</li><ul><li>forename: 'Kate'</li><li>surname: 'Jones'</li><li>address</li><ul><li>AddressLine1: '29 Acacia Avenue'</li><li>AddressLine2: 'None'</li><li>PostTown: 'London'</li><li>Postcode: 'N10 2BC'</li></ul></ul></ul></ul>"

两个选项的格式化输出如下所示: 格式化输出如下所示:

<ul>
    <li>employees</li>
    <ul>
        <li>1</li>
        <ul>
            <li>forename: 'Jack'</li>
            <li>surname: 'Smith'</li>
            <li>address</li>
            <ul>
                <li>AddressLine1: '59 Never Street'</li>
                <li>AddressLine2: 'Flat 10'</li>
                <li>PostTown: 'London'</li>
                <li>Postcode: 'E1 1AB'</li>
            </ul>
        </ul>
        <li>2</li>
        <ul>
            <li>forename: 'Kate'</li>
            <li>surname: 'Jones'</li>
            <li>address</li>
            <ul>
                <li>AddressLine1: '29 Acacia Avenue'</li>
                <li>AddressLine2: 'None'</li>
                <li>PostTown: 'London'</li>
                <li>Postcode: 'N10 2BC'</li>
            </ul>
        </ul>
    </ul>
</ul>

相关问题 更多 >