将 ansible 字典列表值转换为键,将键转换为值
Convert ansible dictionary list values to keys and keys to values
我有一个场景需要将字典 dict1
转换为 Ansible 剧本中的 dict2
,如下所示
dict1 = {'a':[1,2,3],'b':[4,5,6]}
dict2 = {1: 'a', 2: 'a', 3: 'a', 4: 'b', 5: 'b', 6: 'b'}
我尝试了 with_nested
、with_items
但没能成功。
有点难看,但无需在任务中使用 set_fact
即可完成工作,这使您可以自由地在任何地方声明变量(例如库存、剧本、角色默认值或变量、外部文件...) .
该解决方案使用 json_query
(需要在控制器上安装额外的收集和 pip 模块,请参阅 documentation)因为 items2dict
无法使用嵌套元素,因为 key/value 参考资料。
解决方案中的 map('flatten')
是 jmespath(json_query
使用的库)中的“错误”的解决方法,它无法直接处理 subelements
返回的元组:它转换将每个元素放入一个列表中,其中索引可以在 json_query
中正确使用
我没有花时间查看是否可以像您要求的那样将索引转换为整数。照原样,最后的 items2dict
将它们转换回字符串表示形式。如果这是不可接受的,您将不得不进一步搜索。
注意:以下示例将在 ansible >= 2.10 中运行。对于旧版本,您必须在 dict2
表达式中添加一些中间 list
过滤器。
剧本:
- hosts: localhost
gather_facts: false
vars:
dict1: {'a':[1,2,3],'b':[4,5,6]}
transform_q: >-
[*].{"key": [1], "value": [0].key}
dict2: "{{ dict1 | dict2items | subelements('value') | map('flatten')
| json_query(transform_q) | items2dict }}"
tasks:
- debug:
var: dict2
给出:
PLAY [localhost] *******************************************************************************************
TASK [debug] ***********************************************************************************************
ok: [localhost] => {
"dict2": {
"1": "a",
"2": "a",
"3": "a",
"4": "b",
"5": "b",
"6": "b"
}
}
PLAY RECAP *************************************************************************************************
localhost : ok=1 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
例如
- set_fact:
dict2: "{{ dict2|d({})|
combine(dict(item.value|product([item.key]))) }}"
loop: "{{ dict1|dict2items }}"
给予
dict2:
1: a
2: a
3: a
4: b
5: b
6: b
我有一个场景需要将字典 dict1
转换为 Ansible 剧本中的 dict2
,如下所示
dict1 = {'a':[1,2,3],'b':[4,5,6]}
dict2 = {1: 'a', 2: 'a', 3: 'a', 4: 'b', 5: 'b', 6: 'b'}
我尝试了 with_nested
、with_items
但没能成功。
有点难看,但无需在任务中使用 set_fact
即可完成工作,这使您可以自由地在任何地方声明变量(例如库存、剧本、角色默认值或变量、外部文件...) .
该解决方案使用 json_query
(需要在控制器上安装额外的收集和 pip 模块,请参阅 documentation)因为 items2dict
无法使用嵌套元素,因为 key/value 参考资料。
map('flatten')
是 jmespath(json_query
使用的库)中的“错误”的解决方法,它无法直接处理 subelements
返回的元组:它转换将每个元素放入一个列表中,其中索引可以在 json_query
我没有花时间查看是否可以像您要求的那样将索引转换为整数。照原样,最后的 items2dict
将它们转换回字符串表示形式。如果这是不可接受的,您将不得不进一步搜索。
注意:以下示例将在 ansible >= 2.10 中运行。对于旧版本,您必须在 dict2
表达式中添加一些中间 list
过滤器。
剧本:
- hosts: localhost
gather_facts: false
vars:
dict1: {'a':[1,2,3],'b':[4,5,6]}
transform_q: >-
[*].{"key": [1], "value": [0].key}
dict2: "{{ dict1 | dict2items | subelements('value') | map('flatten')
| json_query(transform_q) | items2dict }}"
tasks:
- debug:
var: dict2
给出:
PLAY [localhost] *******************************************************************************************
TASK [debug] ***********************************************************************************************
ok: [localhost] => {
"dict2": {
"1": "a",
"2": "a",
"3": "a",
"4": "b",
"5": "b",
"6": "b"
}
}
PLAY RECAP *************************************************************************************************
localhost : ok=1 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
例如
- set_fact:
dict2: "{{ dict2|d({})|
combine(dict(item.value|product([item.key]))) }}"
loop: "{{ dict1|dict2items }}"
给予
dict2:
1: a
2: a
3: a
4: b
5: b
6: b