例如我有这样的列表:
[{'a': 1, 'b': 2, 'c': 3}, {'a': 1, 'b': 2, 'c': 3}, {'a': 1, 'b': 2, 'c': 3}]
字典有 3 个键,但我只想要其中 2 个键,所以我想过滤列表和字典来创建:
[{'a': 1, 'c': 3}, {'a': 1, 'c': 3}, {'a': 1, 'c': 3}]
如何使用 ansible/jinjia2 过滤器执行此操作?
最佳答案
还有更多选择。给定列表
l1:
- {a: 1, b: 2, c: 3}
- {a: 1, b: 2, c: 3}
- {a: 1, b: 2, c: 3}
l2: [a, c]
- 使用过滤器ansible.utils.keep_keys 。声明变量
l3: "{{ l1|ansible.utils.keep_keys(target=l2) }}"
给出
l3:
- {a: 1, c: 3}
- {a: 1, c: 3}
- {a: 1, c: 3}
- 下面的迭代给出了相同的结果
- set_fact:
l3: "{{ l3|d([]) + [dict(_keys|zip(_vals))] }}"
loop: "{{ l1 }}"
vars:
_keys: "{{ l2 }}"
_vals: "{{ l2|map('extract', item) }}"
- 下一个选项是(错误)使用 omit 。下面的任务给出了相同的结果
- set_fact:
l3: "{{ l1|map('combine', {'b': omit}) }}"
- 这可以通过迭代被拒绝的键来概括
- set_fact:
l3: "{{ l3|d(l1)|map('combine', {item: omit}) }}"
loop: "{{ l1.0.keys()|difference(l2) }}"
用于测试的完整剧本示例
- hosts: all
vars:
l1:
- {a: 1, b: 2, c: 3}
- {a: 1, b: 2, c: 3}
- {a: 1, b: 2, c: 3}
l2: [a, c]
l3: "{{ l1|ansible.utils.keep_keys(target=l2) }}"
tasks:
- block:
- debug:
var: l3|to_yaml
- set_fact:
l3: "{{ l3 + [dict(_keys|zip(_vals))] }}"
loop: "{{ l1 }}"
vars:
l3: []
_keys: "{{ l2 }}"
_vals: "{{ l2|map('extract', item) }}"
- debug:
var: l3|to_yaml
- set_fact:
l3: "{{ l1|map('combine', {'b': omit}) }}"
- debug:
var: l3|to_yaml
- set_fact:
l3: "{{ l3|map('combine', {item: omit}) }}"
loop: "{{ l1.0.keys()|difference(l2) }}"
vars:
l3: "{{ l1 }}"
- debug:
var: l3|to_yaml
run_once: true
关于ansible - 如何从字典列表中获取子集字典?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/68754594/