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

如何在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 
      }}

分步解释(适合新手理解):

  1. my_dict | dict2items:将原始字典转为键值对列表,结构为[{key: 'id1', value: 'name1'}, {key: 'id2', value: 'name2'}, ...]
  2. groupby('value'):按value字段分组,得到[('name1', [{'key':'id1',...}, {'key':'id3',...}]), ('name2', [...]), ...]
  3. items2dict(key_name='0', value_name='1'):将分组结果转为字典,此时值是包含键值对的列表
  4. dict2items:再次转为键值对列表,方便后续处理每个分组的内容
  5. map('combine', {'value': item.value | map(attribute='key') | list}):提取每个分组里的key字段,组成对应的值列表
  6. 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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.10 10:22:52