如何以指定属性为索引,用字典列表对源字典列表执行搜索替换?
基于索引键'k'的字典列表搜索替换实现
需求说明
以字典的k字段作为匹配索引,使用指定的搜索替换字典列表对源字典列表执行以下操作:
- 若源字典的
k值与某条替换字典的k值匹配:用替换字典中的键值对覆盖源字典对应键,保留源字典未被覆盖的键;若源字典缺少替换字典中的键,则新增该键值对 - 若源字典无匹配的替换字典:保持原字典内容不变
- 若替换字典的
k值在源列表中无匹配:直接跳过该替换条目
源字典列表
- k: aaa v: 1 - k: bbb v: 2 - k: bbb v: 3 v2: should be kept from source - k: bbb - k: ccc v: 4
搜索替换字典列表
- k: bbb # 匹配源列表中k=bbb的条目,替换/新增v:99 v: 99 - k: ccc # 匹配源列表中k=ccc的条目,替换/新增v:88和v2:77 v: 88 v2: 77 - k: xxxxx # 源列表无匹配条目,直接跳过 v: 66
期望处理结果
- k: aaa # 无匹配索引:保留源内容 v: 1 - k: bbb # 匹配索引:替换v的值 v: 99 - k: bbb # 匹配索引:替换v的值,保留源中的v2 v: 99 v2: should be kept from source - k: bbb # 匹配索引:新增缺失的v:99 v: 99 - k: ccc # 匹配索引:替换v的值,新增v2:77 v: 88 v2: 77
基于Ansible现有过滤器的实现方案
可以通过loop结合selectattr、first和combine过滤器实现需求,示例Playbook代码如下:
- hosts: localhost vars: source_list: - k: aaa v: 1 - k: bbb v: 2 - k: bbb v: 3 v2: should be kept from source - k: bbb - k: ccc v: 4 replacement_list: - k: bbb v: 99 - k: ccc v: 88 v2: 77 - k: xxxxx v: 66 tasks: - name: 执行字典列表的搜索替换处理 set_fact: processed_list: "{{ processed_list | default([]) + [item | combine(replacement_dict, recursive=False)] }}" loop: "{{ source_list }}" vars: # 从替换列表中匹配当前条目的k值,无匹配则返回空字典 replacement_dict: "{{ replacement_list | selectattr('k', 'equalto', item.k) | first | default({}, true) }}" - name: 输出处理结果 debug: var: processed_list
逻辑说明
- 遍历源字典列表中的每个条目
item - 通过
selectattr筛选出替换列表中k值与当前条目匹配的第一个字典,无匹配时返回空字典 - 使用
combine过滤器将源条目与匹配到的替换字典合并:替换字典的键会覆盖源条目对应键,源条目未被覆盖的键保留,同时新增替换字典中存在但源条目不具备的键
内容的提问来源于stack exchange,提问作者Niki Waibel
相关产品推荐
相关产品推荐

