如何在Ansible中反转字典:将值映射为含对应键的列表
Ansible 字典反转:将键值映射转为值对应键列表
我有一个如下所示的字典(实际规模更大):
my_dict: "id1": "name1" "id2": "name2" "id3": "name1" "id4": "name2" "id5": "name1" "id6": "name3"
需要在Ansible中创建任务,将该字典反转成如下形式:
result_dict: "name1": ["id1", "id3", "id5"] "name2": ["id2", "id4"] "name3": ["id6"]
我尝试了以下任务,但不知道如何向已存在的列表中追加元素,请问有没有更优的实现方法?
- name: "Get list of unique ids" set_fact: unique_names: "{{ my_dict.values() | unique }}" - name: "Initialize result_dict with empty lists" set_fact: result_dict: "{{ result_dict | combine(item: []) }}" loop: "{{ unique_names }}" - name: "Populate result_dict lists" set_fact: result_dict: "{{ result_dict | combine(new_item, recursive=true)}}" vars: new_item: "{ '{{ item.value }}': { item.value: item.key } }" with_dict: "{{ result_dict }}" loop: "{{ my_dict | dict2items }}"
最优实现方法
Ansible原生的groupby过滤器可以一步完成这个需求,不需要分步初始化和循环追加:
- name: 反转字典,按值分组对应键列表 set_fact: result_dict: >- {{ my_dict | dict2items | groupby('value') | items2dict(key_name='0', value_name='1') | dict2items | map('combine', {'value': item.value | map(attribute='key') | list}) | items2dict }}
分步解释(适合新手理解):
my_dict | dict2items:将原始字典转为键值对列表,结构为[{key: 'id1', value: 'name1'}, {key: 'id2', value: 'name2'}, ...]groupby('value'):按value字段分组,得到[('name1', [{'key':'id1',...}, {'key':'id3',...}]), ('name2', [...]), ...]items2dict(key_name='0', value_name='1'):将分组结果转为字典,此时值是包含键值对的列表dict2items:再次转为键值对列表,方便后续处理每个分组的内容map('combine', {'value': item.value | map(attribute='key') | list}):提取每个分组里的key字段,组成对应的值列表items2dict:最终转换为目标格式的字典
如果你觉得链式写法太紧凑,也可以拆分成多个步骤逐步验证:
- name: 将字典转为键值对列表 set_fact: dict_items: "{{ my_dict | dict2items }}" - name: 按value字段分组 set_fact: grouped_items: "{{ dict_items | groupby('value') }}" - name: 转换为初始字典结构 set_fact: interim_dict: "{{ grouped_items | items2dict(key_name='0', value_name='1') }}" - name: 提取每个分组的key组成列表,生成最终字典 set_fact: result_dict: "{{ result_dict | combine({item.key: item.value | map(attribute='key') | list}) }}" loop: "{{ interim_dict | dict2items }}" vars: result_dict: {}
你之前代码的问题
你的代码存在两个核心问题:
new_item用字符串拼接字典的方式容易出错,Ansible中应该用原生字典构造语法- 循环逻辑混乱,同时使用
with_dict和loop导致遍历对象错误
使用groupby可以完全规避这些问题,代码更简洁高效,尤其适合处理大规模字典。
内容的提问来源于stack exchange,提问作者sammy7
相关产品推荐
相关产品推荐

