I have multiple lists as input (all lists have the same length, but the input can have more than 3 lists). I want to create a list which is a sum of all input lists alternating their elements.
For example, given the following input:
data:
- ['1','2','3','4','5']
- ['6','7','8','9','10']
- ['11','12','13','14','15']
I'm expecting the following output:
lst: [['1','6','11'],['2','7','12'],['3','8','13'],['4','9','14'],['5','10','15']]
This is what I've tried:
---
- 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 }}"
The first set_fact
outputs loop elements but lst
doesn't include the actual output I expect. And the limitation of the first set_fact
is that I can't iterate in the loop due to zip
filter. I don't know how to acheive my goal.
Preliminary note: list
being the name of a jinja2 filter, I very strongly suggest you do not use it as a variable name
Ansible being mainly python compatible, you can take advantage of the *
unpacking operator to turn your list elements into arguments to the function/filter you are calling which is accepting a variable number of arguments (as zip
or lookup
below).
The following playbook will work with any number of lists in data_list
(as far as this number is stricly superior to 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 }}"
and gives:
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