You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何使用Jinja2向嵌套列表追加组合字段?

为嵌套字典列表批量添加组合字段uid

问题背景

现有通过Ansible read_csv模块提取的嵌套字典列表数据集:

[
        {
            "id": "1",
            "name": "apple",
            "quantity": "10",
            "type": "fruit"
        },
        {
            "id": "2",
            "name": "orange",
            "quantity": "20",
            "type": "fruit"
        },
        {
            "id": "3",
            "name": "carrot",
            "quantity": "5",
            "type": "veg"
        },
        {
            "id": "4",
            "name": "beetroot",
            "quantity": "2",
            "type": "veg"
        }
]

需要为列表中的每个字典追加uid字段,字段值由type-name-id组合而成,预期结果如下:

[
        {
            "uid": "fruit-apple-1",
            "id": "1",
            "name": "apple",
            "quantity": "10",
            "type": "fruit"
        },
        {
            "uid": "fruit-orange-2",
            "id": "2",
            "name": "orange",
            "quantity": "20",
            "type": "fruit"
        },
        {
            "uid": "veg-carrot-3",
            "id": "3",
            "name": "carrot",
            "quantity": "5",
            "type": "veg"
        },
        {
            "uid": "veg-beetroot-4",
            "id": "4",
            "name": "beetroot",
            "quantity": "2",
            "type": "veg"
        }
]

由于列表规模较大,希望避免使用Ansible循环,改用纯Jinja实现。此前尝试的代码仅生成了uid值的扁平列表,无法保留原有嵌套结构:

- jinja_list: |-
    {% set uid = [] %}
    {% for item in fruits_csv_list.list %}
    {% set li = item.type + '-' +  item.name + '-' +  item.id %}
    {{uid.append(li)}}
    {%- endfor %}
    {{uid}}  

解决方案

使用Jinja的字典合并+列表处理逻辑,直接生成包含uid字段的新嵌套列表,全程由Jinja处理,不触发Ansible循环:

写法一(兼容全版本Jinja2)

- set_fact:
    updated_fruits_list: >
      {% set ns = namespace(result=[]) %}
      {% for item in fruits_csv_list.list %}
          {% set updated_item = item | combine({'uid': '{}-{}-{}'.format(item.type, item.name, item.id)}) %}
          {% set ns.result = ns.result + [updated_item] %}
      {% endfor %}
      {{ ns.result }}

写法二(简洁高效,需Jinja2支持列表推导)

- set_fact:
    updated_fruits_list: "{{ fruits_csv_list.list | map('combine', {'uid': '{}-{}-{}'.format(item.type, item.name, item.id)}) | list }}"

核心逻辑说明

  1. 通过combine过滤器将生成的uid键值对合并到原字典中,保留所有原有字段的同时添加新字段
  2. 两种写法均避免了Ansible的循环迭代,依赖Jinja的内部处理,对大规模数据更高效
  3. 第一种写法用namespace变量解决Jinja循环内的变量作用域问题,确保结果能正确累积

内容的提问来源于stack exchange,提问作者diaryfolio

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.05 17:40:31