# Add/substract to list items - but without a loop

**URL:** <https://forum.ansible.com/t/add-substract-to-list-items-but-without-a-loop/36235>\
**Category:** Ansible Project\
**Created:** [January 21, 2022, 1:14pm UTC](https://forum.ansible.com/t/add-substract-to-list-items-but-without-a-loop/36235 "2022-01-21T13:14:04Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![Dick\_Visser](https://avatars.discourse-cdn.com/v4/letter/d/d9b06d/32.png) [@Dick\_Visser](https://forum.ansible.com/u/Dick_Visser)\
**Post date:** [January 21, 2022, 1:14pm UTC](https://forum.ansible.com/t/add-substract-to-list-items-but-without-a-loop/36235/1 "2022-01-21T13:14:04Z")

</div>

Hi

I have this list of ints:

selection:

- 1
- 4
- 5
- 7

I’d like to subtract 1 from each item, so that I will end up with:

selection:

- 0
- 3
- 4
- 6

I’d like to avoid adding an intermediary set\_fact loop to do the math.  
If I define this filter:

def subtract(number, amount=1):  
return number - amount

Then I can accomplish what I want using:

selection\>map(‘subtract’)

which is reasonably clean and understandable.

But before I add a new filter - is there any other way to achieve this?

thx

---

<div class="post-metadata">

**Author:** ![utoddl](https://sea1.discourse-cdn.com/ansible/user_avatar/forum.ansible.com/utoddl/32/249_2.png) [@utoddl](https://forum.ansible.com/u/utoddl)\
**Post date:** [January 21, 2022, 1:42pm UTC](https://forum.ansible.com/t/add-substract-to-list-items-but-without-a-loop/36235/2 "2022-01-21T13:42:39Z")

</div>

I’m not proud of this, but it works:

```auto
---
- name: List subtraction
  gather_facts: no
  hosts: localhost
  vars:
    selection: [1, 4, 5, 7]
  tasks:
    - name: Subtract one from each selection
      debug:
        msg: "{% set result = [] -%}
              {% for v in selection -%}
              {% set _ = result.append(v - 1) -%}
              {% endfor %}{{ result }}"

```

---

<div class="post-metadata">

**Author:** ![utoddl](https://sea1.discourse-cdn.com/ansible/user_avatar/forum.ansible.com/utoddl/32/249_2.png) [@utoddl](https://forum.ansible.com/u/utoddl)\
**Post date:** [January 21, 2022, 2:10pm UTC](https://forum.ansible.com/t/add-substract-to-list-items-but-without-a-loop/36235/3 "2022-01-21T14:10:52Z")

</div>

This also works:

```auto
---
- name: List subtraction
  gather_facts: no
  hosts: localhost
  vars:
    selection: [1, 4, 5, 7]
  tasks:
    - name: Subtract one from each selection
      debug:
        msg: "{{ selection| zip_longest([-1], fillvalue=-1) | map('sum') }}"

```

​

---

<div class="post-metadata">

**Author:** ![flowerysong1](https://avatars.discourse-cdn.com/v4/letter/f/ecae2f/32.png) [@flowerysong1](https://forum.ansible.com/u/flowerysong1)\
**Post date:** [January 21, 2022, 2:16pm UTC](https://forum.ansible.com/t/add-substract-to-list-items-but-without-a-loop/36235/4 "2022-01-21T14:16:04Z")

</div>

This is a little weird because of the use of zip() to turn the list of integers into a list of lists, but still fairly readable IMO:

foo | zip | map(‘sum’, start=-1)

---

<div class="post-metadata">

**Author:** ![vbotka](https://sea1.discourse-cdn.com/ansible/user_avatar/forum.ansible.com/vbotka/32/359_2.png) [@vbotka](https://forum.ansible.com/u/vbotka)\
**Post date:** [January 21, 2022, 3:01pm UTC](https://forum.ansible.com/t/add-substract-to-list-items-but-without-a-loop/36235/5 "2022-01-21T15:01:29Z")

</div>

You can use \*product\* instead of \*zip\*, e.g.

&nbsp;&nbsp;selection | product([-1]) | map('sum')

---

<div class="post-metadata">

**Author:** ![Dick\_Visser](https://avatars.discourse-cdn.com/v4/letter/d/d9b06d/32.png) [@Dick\_Visser](https://forum.ansible.com/u/Dick_Visser)\
**Post date:** [January 21, 2022, 7:05pm UTC](https://forum.ansible.com/t/add-substract-to-list-items-but-without-a-loop/36235/6 "2022-01-21T19:05:30Z")

</div>

This is the clear winner - thx 🙂
