如何利用Ansible内置过滤器将字典列表转换为以唯一属性为键的字典
如何利用Ansible内置过滤器将字典列表转换为以唯一属性为键的字典
当然有现成的内置方案!完全不用自己写Python插件,用Ansible自带的过滤器组合就能轻松实现你想要的结构转换,而且非常灵活。
先给你最贴合需求的实现方式,针对你提供的ansible_mounts场景:
- name: 将挂载点列表转换为以device为键的字典 set_fact: mounts_by_device: "{{ dict(ansible_mounts | map(attribute='device') | zip(ansible_mounts | map('omit', 'device'))) }}"
拆解一下这个过滤器组合的作用:
- 提取键列表:
ansible_mounts | map(attribute='device')
从每个挂载点字典中取出device字段的值,生成一个所有设备路径的列表,比如['/dev/sda1', '/dev/mapper/rootvg-rootlv', ...]。 - 生成值列表:
ansible_mounts | map('omit', 'device')
对每个挂载点字典,移除device字段,保留其他所有属性,生成的列表元素就是你想要的每个键对应的值,比如[{"mount": "/boot/efi", "fstype": "vfat", ...}, ...]。 - 配对并生成字典:
dict(...)
用zip把上面两个列表按位置一一配对,形成(键, 值)的元组结构,再通过dict过滤器直接转换成你期望的字典格式。
转换后的结果和你想要的完全一致:
{ "/dev/sda1": { "mount": "/boot/efi", "fstype": "vfat", "size_available": 202100736, "size_total": 209469440 }, "/dev/mapper/rootvg-rootlv": { "fstype": "xfs", "mount": "/" }, "/dev/mapper/rootvg-homelv": { "fstype": "xfs", "mount": "/home" } }
灵活调整与备选方案:
如果之后你想换成以mount路径作为键,只需要修改两处参数:
mounts_by_mountpoint: "{{ dict(ansible_mounts | map(attribute='mount') | zip(ansible_mounts | map('omit', 'mount'))) }}"
另外,如果你不介意值里保留原键字段(比如device),还可以用更简洁的items2dict过滤器:
mounts_by_device: "{{ ansible_mounts | items2dict(key_name='device') }}"
不过这个生成的字典值里会包含device字段,和你想要的结构略有区别,所以前面的dict+zip+map组合更贴合你的目标。
这种方式完全基于Ansible的核心内置过滤器,不需要依赖任何第三方插件,既简洁又容易维护,刚好匹配你“利用内置工具实现转换”的需求。
内容来源于stack exchange
相关产品推荐
相关产品推荐

