Ansible中使用set_fact将字典列表转换为列表字典的实现问题
Ansible 字典列表分组转换实现方案
问题原因
你原有写法的核心问题有两个:
with_items缩进错误,应该和set_fact平级,不能放在set_fact的参数内部- 使用
combine时直接给对应key赋值为仅包含当前kidname的单元素列表,每次都会覆盖之前已存储的列表内容,所以最终只能保留每个name对应的最后一个kidname
实现方法
方法1:循环追加列表(匹配你原本的实现思路)
构造字典值时先判断对应key是否已经存在,存在就复用已有列表追加新元素,不存在就初始化空列表再追加:
- set_fact: names: "{{ names | default({}) | combine({ item.name: names[item.name] | default([]) + [item.kidname] }) }}" with_items: "{{ family }}"
方法2:使用内置groupby过滤器(更简洁高效)
Ansible 提供的groupby过滤器可以直接按指定字段完成分组,不需要手动写循环逻辑:
# 先对family按name字段分组,再提取每个分组下的所有kidname生成列表 - set_fact: names: {} - set_fact: names: "{{ names | combine({ item.0: item.1 | map(attribute='kidname') | list }) }}" loop: "{{ family | groupby('name') }}"
两种方法执行后names变量的值都会符合你要求的格式。
内容的提问来源于stack exchange,提问作者Lior Lew
相关产品推荐
相关产品推荐

