如何在Ansible中部分扁平化并合并嵌套字典而非完全扁平化?
在Ansible中合并嵌套字典列表为单字典列表
原始数据
我有如下嵌套结构的字典列表:
dict3: [[[{"x": "1","y": "2"},{"z": 3,"h": 4}],{"w": 5}],[[{"x": "333","y": "444"},{"z": "555","h": "777"}],{"w": "999"}]]
目标格式
需要将其转换为每个元素是合并后单字典的列表:
dict: [ { "x": "1", "y": "2", "z": "3", "h": "4", "w": 5 }, { "x": "333", "y": "444", "z": 555, "h": 777, "w": 999 } ]
当前尝试的问题
使用community.general.flattened lookup会将所有元素完全扁平化,但无法合并每组中的x/y/z/h/w字段:
- name: 'unnest' all elements into single list ansible.builtin.debug: msg: "all in one list {{lookup('community.general.flattened', dict)}}"
扁平化后的结果仅拆分了嵌套结构,未合并字典:
"_raw_params": [ { "x": "1", "y": "2" }, { "h": 4, "z": 3 }, { "w": 5 }, { "x": "333", "y": "444" }, { "h": "777", "z": "555" }, { "w": "999" } ]
当前代码
- hosts: localhost gather_facts: false vars: dict: [[[{"x": "1","y": "2"},{"z": 3,"h": 4}],{"w": 5}],[[{"x": "333","y": "444"},{"z": "555","h": "777"}],{"w": "999"}]] tasks: - name: UNNEST set_fact: "{{lookup('community.general.flattened',dict)}}"
解决方案
可以通过循环遍历顶层元素,结合flatten和combine过滤器实现字典合并:
- hosts: localhost gather_facts: false vars: dict: [[[{"x": "1","y": "2"},{"z": 3,"h": 4}],{"w": 5}],[[{"x": "333","y": "444"},{"z": "555","h": "777"}],{"w": "999"}]] tasks: - name: 合并嵌套字典为目标格式 set_fact: merged_dict: "{{ merged_dict | default([]) + [ item | flatten | combine ] }}" loop: "{{ dict }}" - name: 查看结果 debug: var: merged_dict
逻辑说明
loop: "{{ dict }}"遍历原始列表中的每个顶层嵌套单元(即[[{x,y},{z,h}],{w}]结构)item | flatten将当前单元的嵌套结构扁平化,得到[{x,y}, {z,h}, {w}]| combine将扁平化后的多个字典合并为一个完整字典merged_dict | default([]) + [...]把每个合并后的字典添加到结果列表中
额外说明
如果需要对字段类型进行转换(比如目标格式中部分数字字段从字符串转为整数),可以在合并后单独处理,例如:
- name: 转换字段类型(可选) set_fact: merged_dict: "{{ merged_dict | map('combine', {'z': item.z | int, 'h': item.h | int, 'w': item.w | int}) | list }}" loop: "{{ merged_dict }}" when: item.z is string or item.h is string or item.w is string
内容的提问来源于stack exchange,提问作者LJS
相关产品推荐
相关产品推荐

