如何在 Ansible 中交替显示多个列表的元素?
How can I alternate the elements of multiple lists in Ansible?
我有多个列表作为输入(所有列表的长度都相同,但输入可以有 3 个以上的列表)。我想创建一个列表,它是所有输入列表交替其元素的总和。
例如,给定以下输入:
data:
- ['1','2','3','4','5']
- ['6','7','8','9','10']
- ['11','12','13','14','15']
我期待以下输出:
lst: [['1','6','11'],['2','7','12'],['3','8','13'],['4','9','14'],['5','10','15']]
这是我试过的:
---
- name: zip more than 3 lists with loop
hosts: localhost
tasks:
- name: Set facts
set_fact:
list:
- ['1','2','3','4','5']
- ['6','7','8','9','10']
- ['11','12','13','14','15']
- name: zip to make pairs of both lists
set_fact:
lst: "{{ list[0] | zip(list[1]) | zip(list[2]) | list }}"
- name: Debug ['1','6','11'],['2','7','13'],...
debug:
msg: "{{ item | flatten }}"
loop: "{{ lst }}"
- name: zip to make pairs of both lists
set_fact:
lst2: "{{ lst2 | default([]) | zip(ansible_loop.nextitem) | list }}"
loop: "{{ list }}"
loop_control:
extended: yes
- name: Debug
debug:
msg: "{{ lst2 }}"
第一个 set_fact
输出循环元素,但 lst
不包括我期望的实际输出。第一个 set_fact
的限制是由于 zip
过滤器,我无法在循环中迭代。我不知道如何实现我的目标。
给定数据
data:
- ['1','2','3','4','5']
- ['6','7','8','9','10']
- ['11','12','13','14','15']
问:Transpose矩阵。
答:例如
- set_fact:
lst: "{{ lst|d(data.0)|zip(item)|map('flatten') }}"
loop: "{{ data[1:] }}"
给予
lst:
- ['1', '6', '11']
- ['2', '7', '12']
- ['3', '8', '13']
- ['4', '9', '14']
- ['5', '10', '15']
系统的方法是为 Python NumPy package. For example, starting with numpy.matrix.transpose
创建包装器
shell> cat filter_plugins/numpy.py
import json
import numpy
def numpy_transpose(arr):
arr1 = numpy.array(arr)
arr2 = arr1.transpose()
return json.dumps(arr2.tolist())
class FilterModule(object):
''' Ansible wrappers for Python NumPy methods '''
def filters(self):
return {
'numpy_transpose': numpy_transpose,
}
下面的声明在没有迭代的情况下给出了相同的结果
lst: "{{ data|numpy_transpose()|from_yaml }}"
初步说明:list
是jinja2过滤器的名称,我非常强烈建议您不要将其用作变量名
Ansible 主要是 python 兼容,您可以利用 *
解包运算符将您的列表元素转换为您正在调用的 function/filter 的参数,它正在接受一个变量参数数量(如下面的 zip
或 lookup
)。
以下剧本适用于 data_list
中任意数量的列表(只要这个数字严格优于 1...)
---
- name: zip more than 3 lists with loop
hosts: localhost
vars:
data_list:
- ['1','2','3','4','5']
- ['6','7','8','9','10']
- ['11','12','13','14','15']
# You can do this with your original zip tentative
alternated_list1: "{{ (data_list | first) | zip(*data_list[1:]) }}"
# But I find it more elegant with the together lookup here
alternated_list2: "{{ lookup('together', *data_list) }}"
tasks:
- name: calculated with zip
debug:
var: alternated_list1
- name: calculated with together lookup
debug:
var: alternated_list2
- name: And of course you can use the result, for example in a loop
debug:
var: item
loop: "{{ alternated_list2 }}"
并给出:
PLAY [zip more than 3 lists with loop] ********************************************************************************************************************************
TASK [Gathering Facts] ************************************************************************************************************************************************
ok: [localhost]
TASK [calculated with zip] ********************************************************************************************************************************************
ok: [localhost] => {
"alternated_list1": [
[
"1",
"6",
"11"
],
[
"2",
"7",
"12"
],
[
"3",
"8",
"13"
],
[
"4",
"9",
"14"
],
[
"5",
"10",
"15"
]
]
}
TASK [calculated with together lookup] ********************************************************************************************************************************
ok: [localhost] => {
"alternated_list2": [
[
"1",
"6",
"11"
],
[
"2",
"7",
"12"
],
[
"3",
"8",
"13"
],
[
"4",
"9",
"14"
],
[
"5",
"10",
"15"
]
]
}
TASK [And of course you can use the result, for example in a loop] ****************************************************************************************************
ok: [localhost] => (item=['1', '6', '11']) => {
"ansible_loop_var": "item",
"item": [
"1",
"6",
"11"
]
}
ok: [localhost] => (item=['2', '7', '12']) => {
"ansible_loop_var": "item",
"item": [
"2",
"7",
"12"
]
}
ok: [localhost] => (item=['3', '8', '13']) => {
"ansible_loop_var": "item",
"item": [
"3",
"8",
"13"
]
}
ok: [localhost] => (item=['4', '9', '14']) => {
"ansible_loop_var": "item",
"item": [
"4",
"9",
"14"
]
}
ok: [localhost] => (item=['5', '10', '15']) => {
"ansible_loop_var": "item",
"item": [
"5",
"10",
"15"
]
}
PLAY RECAP ************************************************************************************************************************************************************
localhost : ok=4 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
我有多个列表作为输入(所有列表的长度都相同,但输入可以有 3 个以上的列表)。我想创建一个列表,它是所有输入列表交替其元素的总和。
例如,给定以下输入:
data:
- ['1','2','3','4','5']
- ['6','7','8','9','10']
- ['11','12','13','14','15']
我期待以下输出:
lst: [['1','6','11'],['2','7','12'],['3','8','13'],['4','9','14'],['5','10','15']]
这是我试过的:
---
- name: zip more than 3 lists with loop
hosts: localhost
tasks:
- name: Set facts
set_fact:
list:
- ['1','2','3','4','5']
- ['6','7','8','9','10']
- ['11','12','13','14','15']
- name: zip to make pairs of both lists
set_fact:
lst: "{{ list[0] | zip(list[1]) | zip(list[2]) | list }}"
- name: Debug ['1','6','11'],['2','7','13'],...
debug:
msg: "{{ item | flatten }}"
loop: "{{ lst }}"
- name: zip to make pairs of both lists
set_fact:
lst2: "{{ lst2 | default([]) | zip(ansible_loop.nextitem) | list }}"
loop: "{{ list }}"
loop_control:
extended: yes
- name: Debug
debug:
msg: "{{ lst2 }}"
第一个 set_fact
输出循环元素,但 lst
不包括我期望的实际输出。第一个 set_fact
的限制是由于 zip
过滤器,我无法在循环中迭代。我不知道如何实现我的目标。
给定数据
data:
- ['1','2','3','4','5']
- ['6','7','8','9','10']
- ['11','12','13','14','15']
问:Transpose矩阵。
答:例如
- set_fact:
lst: "{{ lst|d(data.0)|zip(item)|map('flatten') }}"
loop: "{{ data[1:] }}"
给予
lst:
- ['1', '6', '11']
- ['2', '7', '12']
- ['3', '8', '13']
- ['4', '9', '14']
- ['5', '10', '15']
系统的方法是为 Python NumPy package. For example, starting with numpy.matrix.transpose
创建包装器shell> cat filter_plugins/numpy.py
import json
import numpy
def numpy_transpose(arr):
arr1 = numpy.array(arr)
arr2 = arr1.transpose()
return json.dumps(arr2.tolist())
class FilterModule(object):
''' Ansible wrappers for Python NumPy methods '''
def filters(self):
return {
'numpy_transpose': numpy_transpose,
}
下面的声明在没有迭代的情况下给出了相同的结果
lst: "{{ data|numpy_transpose()|from_yaml }}"
初步说明:list
是jinja2过滤器的名称,我非常强烈建议您不要将其用作变量名
Ansible 主要是 python 兼容,您可以利用 *
解包运算符将您的列表元素转换为您正在调用的 function/filter 的参数,它正在接受一个变量参数数量(如下面的 zip
或 lookup
)。
以下剧本适用于 data_list
中任意数量的列表(只要这个数字严格优于 1...)
---
- name: zip more than 3 lists with loop
hosts: localhost
vars:
data_list:
- ['1','2','3','4','5']
- ['6','7','8','9','10']
- ['11','12','13','14','15']
# You can do this with your original zip tentative
alternated_list1: "{{ (data_list | first) | zip(*data_list[1:]) }}"
# But I find it more elegant with the together lookup here
alternated_list2: "{{ lookup('together', *data_list) }}"
tasks:
- name: calculated with zip
debug:
var: alternated_list1
- name: calculated with together lookup
debug:
var: alternated_list2
- name: And of course you can use the result, for example in a loop
debug:
var: item
loop: "{{ alternated_list2 }}"
并给出:
PLAY [zip more than 3 lists with loop] ********************************************************************************************************************************
TASK [Gathering Facts] ************************************************************************************************************************************************
ok: [localhost]
TASK [calculated with zip] ********************************************************************************************************************************************
ok: [localhost] => {
"alternated_list1": [
[
"1",
"6",
"11"
],
[
"2",
"7",
"12"
],
[
"3",
"8",
"13"
],
[
"4",
"9",
"14"
],
[
"5",
"10",
"15"
]
]
}
TASK [calculated with together lookup] ********************************************************************************************************************************
ok: [localhost] => {
"alternated_list2": [
[
"1",
"6",
"11"
],
[
"2",
"7",
"12"
],
[
"3",
"8",
"13"
],
[
"4",
"9",
"14"
],
[
"5",
"10",
"15"
]
]
}
TASK [And of course you can use the result, for example in a loop] ****************************************************************************************************
ok: [localhost] => (item=['1', '6', '11']) => {
"ansible_loop_var": "item",
"item": [
"1",
"6",
"11"
]
}
ok: [localhost] => (item=['2', '7', '12']) => {
"ansible_loop_var": "item",
"item": [
"2",
"7",
"12"
]
}
ok: [localhost] => (item=['3', '8', '13']) => {
"ansible_loop_var": "item",
"item": [
"3",
"8",
"13"
]
}
ok: [localhost] => (item=['4', '9', '14']) => {
"ansible_loop_var": "item",
"item": [
"4",
"9",
"14"
]
}
ok: [localhost] => (item=['5', '10', '15']) => {
"ansible_loop_var": "item",
"item": [
"5",
"10",
"15"
]
}
PLAY RECAP ************************************************************************************************************************************************************
localhost : ok=4 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0