Ansible中基于另一字典匹配键值对过滤字典的实现方法
问题原因
difference()过滤器默认做全对象等值匹配,只有两个字典的所有键、值完全一致时才会判定为相等。你场景中my_dict_2的条目缺少name字段,和my_dict_1的完整条目结构不同,所以无法被识别为匹配项,自然不能正确计算差集。
实现方法
核心思路是先提取my_dict_2中用于匹配的build+version键值组合作为排除规则,再遍历my_dict_1保留不在排除规则内的条目即可,不需要依赖额外插件。
可直接使用的任务代码如下:
- name: 按指定键值过滤字典列表差集 debug: var: filtered_res vars: # 提取所有需要排除的build、version组合 exclude_pairs: "{{ my_dict_2 | map(attribute='build') | zip(my_dict_2 | map(attribute='version')) | list }}" # 遍历my_dict_1,过滤掉匹配排除规则的条目 filtered_res: "{{ [item for item in my_dict_1 if (item.build, item.version) not in exclude_pairs] }}" register: output
扩展说明
- 如果后续需要增加匹配键,只需要在
exclude_pairs的zip参数中追加对应属性,同时在判断条件的元组中追加对应字段即可,例如要同时匹配name字段,修改为:exclude_pairs: "{{ my_dict_2 | map(attribute='build') | zip(my_dict_2 | map(attribute='version')) | zip(my_dict_2 | map(attribute='name')) | list }}" filtered_res: "{{ [item for item in my_dict_1 if (item.build, item.version, item.name) not in exclude_pairs] }}" - 上述写法兼容Ansible 2.10及以上版本,基于原生Jinja2列表推导逻辑实现,执行效率高于嵌套循环判断。
执行后output中存储的结果和预期完全一致:
- build: 0.0.20 version: 15.1.3.1 name: HD3.1 - build: 0.0.30 version: 16.1.3.1 name: HD4.1
内容的提问来源于stack exchange,提问作者Virtual Network
相关产品推荐
相关产品推荐

