
本文详解如何在 Ansible Jinja2 模板中将字典(key → list)结构扁平化为单一列表,并支持基于键名正则匹配的动态过滤(如仅保留以 my_ 开头的键对应列表),全程无需 Python 列表推导式。
本文详解如何在 ansible jinja2 模板中将字典(key → list)结构扁平化为单一列表,并全程无需 python 列表推导式。
在 Ansible 的变量处理场景中,常需将形如 {"my_list_a": ["a","b"], "list_c": ["f"]} 的字典结构合并为一个统一列表。由于 Jinja2 在 Ansible 中不支持原生列表推导式,必须依赖 Ansible 内置过滤器链完成此任务。
基础扁平化:values() | flatten
最简洁的方式是直接提取字典所有值(即各 inner list),再用 flatten 过滤器递归展开:
my_combined_list: "{{ my_dict.values() | flatten }}"该表达式会将 my_dict 中每个键对应的列表依次展开,生成扁平列表 [a, b, c, a, d, e, f]。注意:flatten 默认深度为 1,对单层嵌套列表完全适用;若内部存在更深嵌套(如 ["a", ["b", "c"]]),可显式指定 | flatten(2) 控制展开层级。
条件筛选:按键名动态过滤(如仅含 my_ 前缀)
当需排除特定键(如 list_c),应先将字典转为键值对列表(dict2items),再使用 selectattr 结合字符串测试(如 match)筛选,最后提取值并扁平化:
allow_match: [my_]
my_combined_list: >-
{{ my_dict | dict2items
| selectattr('key', 'match', allow_match|join('|'))
| map(attribute='value')
| flatten }}- dict2items 将字典转为 [{"key":"my_list_a","value":["a","b"]}, ...] 格式;
- selectattr('key', 'match', "my_|list_") 支持正则多模式匹配(allow_match|join('|') 生成 "my_|list_");
- map(attribute='value') 提取所有匹配项的 value 字段(即原始列表);
- 最终 flatten 合并为单层列表。
✅ 注意事项:
- match 测试默认启用正则,my_ 等价于 ^my_(行首匹配),确保精准识别前缀;
- 若需忽略大小写,改用 search 测试并添加 (?i) 标志:'search', '(?i)^my_';
- flatten 对空列表安全,不会报错,适合处理含空值的字典;
- 如需去重+排序,可在末尾追加 | unique | sort(例如 | flatten | unique | sort)。
完整可运行示例:
- hosts: localhost
vars:
my_dict:
my_list_a: [a, b, c]
my_list_b: [a, d, e]
list_c: [f]
# 扁平化全部
all_flattened: "{{ my_dict.values() | flatten }}"
# 仅匹配 my_* 键
my_only: >-
{{ my_dict | dict2items
| selectattr('key', 'match', 'my_')
| map(attribute='value')
| flatten }}
tasks:
- debug: var=all_flattened
- debug: var=my_only输出结果清晰区分全量与条件合并效果,是构建动态配置清单、服务发现列表或资源聚合场景的理想实践。

















