【问题标题】:Convert dictionary in list转换列表中的字典
【发布时间】:2022-01-15 00:19:14
【问题描述】:

我有以下 json 文件

[
    {
        "v4-filter": {
            "accept_to_test1t": {
                "action": "accept"
            },
            "access_to_test2": [
                {
                    "source-prefix-list": "x.x.x.x/yy"
                },
                {
                    "destination-prefix-list": "x.x.x.x/yy"
                },
                {
                    "action": "accept"
                }
            ]
        }
    }
]

请注意,字典键 accept_to_test1 的值又是字典 "action": "accept" 问题:我需要在列表中转换所有嵌套字典,如上面的 case。 在这种特定情况下,例如

accept_to_test1 : [{"action": "accept"}]。 其余的都保持原样。 结果:

[
    {
        "v4-filter": {
            "accept_to_test1t": [
            {
                "action": "accept"
            }],
            "access_to_test2": [
            ... like before ...
        }
    }
]

我正在使用 jinja2 模板来呈现这些数据,它可以工作,但仅适用于字典列表。

{%- for d  in data_list -%}
    {%- for k,v  in d.items() -%} 
        {%- for term,value  in v.items() -%} 
        term {{ term  }} {{ '{ \n' }}
          {%- set label = namespace(source=false, dest=false, port=false, action=false, prot=false) -%}
          {%- for dict_item in value -%}
            {%- for key, value in dict_item.items()  -%}            
               {% if  key == "source-prefix-list" %}
               {% if not label.source %}  source-address::{% else %}{{ ' '*18 }}{% endif %} {{value}} {{ '\n' }}  
               {%- set label.source = true -%}
               {% endif %}
               {%- if  key == "destination-prefix-list" -%}
               {% if not label.dest %}  destination-address::{% else %}{{ ' '*20 }}{% endif %} {{value}} {{ '\n' }}  
               {%- set label.dest = true %} 
               {%- endif -%}
               {%- if  key == "destination-port" -%}
               {% if not label.port %}  destination-port::{% else %}{{ ' '*20 }}{% endif %} {{value}} {{ '\n' }}
               {%- set label.port = true -%}  
               {% endif %}
               {%- if  key == "action" -%}
               {% if not label.action %}  action::{% else %}{{ ' '*20 }}{% endif %} {{value}} {{ '\n' }}
               {%- set label.action = true -%}  
               {% endif %}
               {%- if  key == "protocol" -%}
               {% if not label.protocol %}  protocol::{% else %}{{ ' '*20 }}{% endif %} {{value}} {{ '\n' }}
               {%- set label.protocol = true -%}  
               {% endif %}
            {%- endfor -%}
          {%- endfor -%}
          {{ '} \n\n' }}
        {%- endfor -%}
    {%- endfor -%} 
{%- endfor -%} 
{# above template is for json file #}

渲染过程中出现问题

    {%- for key, value in dict_item.items()  -%}            
  jinja2.exceptions.UndefinedError: 'str object' has no attribute 'item

由于 {'action': 'accept'} 不是可迭代项。 它适用于 [{'action': 'accept'}]。

欢迎任何提示。

谢谢。

【问题讨论】:

  • # if li 是你的列表

标签: json python-3.x list dictionary jinja2


【解决方案1】:

解决这个问题的一个简单方法是检测value 变量何时是一个字典,然后将其嵌入到一个列表中。对于检测,我们可以使用mapping bultin 测试。嵌入是一个简单的封装:{%- set value_list = [value] %}

{%- for d  in data_list -%}
    {%- for k,v  in d.items() -%}
        {%- for term,value  in v.items() -%}
        term {{ term  }} {{ '{ \n' }}
        {%- set label = namespace(source=false, dest=false, port=false, action=false, prot=false) -%}
        {%- if value is mapping() %}
            {%- set value_list = [value] %}
        {%- else %}
            {%- set value_list = value %}
        {%- endif %}
        {%- for dict_item in value_list -%}
            {%- for key, value in dict_item.items() -%}
            {%- if  key == "source-prefix-list" %}
            {%- if not label.source %}  source-address::{% else %}{{ ' '*18 }}{% endif %} {{value}} {{ '\n' }}
            {%- set label.source = true -%}
            {%- endif %}
            {%- if  key == "destination-prefix-list" -%}
            {%- if not label.dest %}  destination-address::{% else %}{{ ' '*20 }}{% endif %} {{value}} {{ '\n' }}
            {%- set label.dest = true %}
            {%- endif -%}
            {%- if  key == "destination-port" -%}
            {%- if not label.port %}  destination-port::{% else %}{{ ' '*20 }}{% endif %} {{value}} {{ '\n' }}
            {%- set label.port = true -%}
            {%- endif %}
            {%- if  key == "action" -%}
            {%- if not label.action %}  action::{% else %}{{ ' '*20 }}{% endif %} {{value}} {{ '\n' }}
            {%- set label.action = true -%}
            {%- endif %}
            {%- if  key == "protocol" -%}
            {%- if not label.protocol %}  protocol::{% else %}{{ ' '*20 }}{% endif %} {{value}} {{ '\n' }}
            {%- set label.protocol = true -%}
            {%- endif %}
            {%- endfor -%}
        {%- endfor -%}
        {{ '} \n\n' }}
        {%- endfor -%}
    {%- endfor -%}
{%- endfor -%}

输出:

term accept_to_test1t { 
  action:: accept 
} 

term access_to_test2 { 
  source-address:: x.x.x.x/yy 
  destination-address:: x.x.x.x/yy 
  action:: accept 
} 

我还修复了一些缩进问题。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-02-10
    • 2017-04-23
    • 2021-10-13
    • 1970-01-01
    • 1970-01-01
    • 2018-08-21
    相关资源
    最近更新 更多