如何在Ansible中修改现有字典,将列表元素添加至对应子字典
解决Ansible中给现有字典子项添加列表值的问题
我来帮你搞定这个字典合并的需求!你的核心目标是把env_homes列表里的每个路径,对应添加到jbossvars.environments中每个环境的子字典里作为key3。原来的playbook写法没达到效果,主要是因为没有正确关联环境和对应的路径,且在错误的层级做了字典合并。
问题分析
你原来的代码里:
- 第一个
set_fact构建的env_homes字典结构完全错误,把TEST_ENV的值变成了原字典加列表的组合,不是我们需要的key3键值对; - 第二个
combine操作是在顶层字典做合并,会直接覆盖TEST_ENV的原有值,而不是在子字典里追加新键。
正确实现方法
下面的方案假设env_homes列表的顺序和jbossvars.environments中环境key的顺序完全匹配(比如第一个路径对应TEST_ENV,第二个对应TEST_ENV2),这和你给出的示例结构一致:
- name: Generate updated environments dict with key3 set_fact: updated_envs: >- {% set env_keys = jbossvars.environments.keys() | list %} {% set new_env_dict = {} %} {% for env_key, home_path in zip(env_keys, env_homes) %} {% set _ = new_env_dict.update({ env_key: jbossvars.environments[env_key] | combine({'key3': home_path}) }) %} {% endfor %} {{ new_env_dict }} - name: Assemble the final new_dict set_fact: new_dict: jbossvars: environments: "{{ updated_envs }}" - name: Debug the result debug: var: new_dict
代码解释
- 获取环境key列表:先把
jbossvars.environments的key转成列表,确保能和env_homes按顺序一一对应; - 循环构建新字典:用
zip把环境key和对应的home路径配对,然后对每个环境的原有子字典,用combine方法追加key3: home_path的键值对,更新到新字典中; - 组装最终字典:把更新后的
environments字典放到jbossvars下,得到你想要的new_dict结构。
更简洁的写法(利用Jinja2高阶函数)
如果喜欢更紧凑的写法,可以用dict2items和map来实现,效果完全一样:
- name: Create new_dict directly set_fact: new_dict: jbossvars: environments: >- {{ dict( zip( jbossvars.environments.keys(), jbossvars.environments.values() | zip(env_homes) | map('combine', {'key3': item[1]}) ) ) }}
运行后,你就能得到期望的new_dict结构:每个环境的子字典里都新增了key3,对应正确的home路径。
内容的提问来源于stack exchange,提问作者arnoutvh
相关产品推荐
相关产品推荐

