Skip to content

Working With Lists


Two chapters ago, + on two strings misbehaved by concatenating them when you might have wanted arithmetic. Last chapter, + on two numbers did real addition. Here’s the third case, and the one where + finally does exactly what it looks like it should: joining two lists together.

Concatenation With +

vars:
  list_a: [1, 2, 3]
  list_b: [4, 5, 6]
tasks:
  - name: Concatenate lists
    ansible.builtin.debug:
      msg: "{{ list_a + list_b }}"
[1, 2, 3, 4, 5, 6]

No surprises, no type-conversion gotchas — + on two lists genuinely concatenates them, in order. This is the one case in this section where + is simply correct on its own, with nothing extra to remember.

unique — Removing Duplicates

msg: "{{ [1, 2, 2, 3, 3, 3] | unique }}"
[1, 2, 3]

sort And reverse

msg: "{{ [3, 1, 2] | sort }}"
[1, 2, 3]
msg: "{{ [1, 2, 3] | reverse }}"
[3, 2, 1]

min, max, sum

vars:
  numbers: [3, 1, 4, 1, 5]
tasks:
  - name: Show min, max, sum
    ansible.builtin.debug:
      msg: "min={{ numbers | min }} max={{ numbers | max }} sum={{ numbers | sum }}"
min=1 max=5 sum=14

first And last

msg: "{{ [10, 20, 30] | first }} {{ [10, 20, 30] | last }}"
10 30

length (Recap)

length isn’t string-specific, as mentioned back in Chapter 1 — on a list, it’s simply the element count:

msg: "{{ [1, 2, 3] | length }}"
3

flatten — Collapsing Nested Lists

msg: "{{ [[1, 2], [3, [4, 5]]] | flatten }}"
[1, 2, 3, 4, 5]

By default, flatten collapses every level of nesting, however deep. Limit it to a specific depth with levels:

msg: "{{ [[1, 2], [3, [4, 5]]] | flatten(levels=1) }}"
[1, 2, 3, [4, 5]]

Only the outermost level got flattened this time — [4, 5] stayed nested, since it was two levels deep from the top.

join (Recap)

Already used in the Jinja2 and magic variables chapters — worth one more mention here since it belongs conceptually with the rest of this chapter’s list tools:

msg: "{{ ['apple', 'banana', 'cherry'] | join(', ') }}"
apple, banana, cherry

A Brief Look At zip

zip pairs up corresponding elements from multiple lists:

msg: "{{ [1, 2, 3] | zip(['a', 'b', 'c']) | list }}"
[[1, 'a'], [2, 'b'], [3, 'c']]

Note the trailing | listzip produces something that needs to be explicitly turned into a real list before it displays the way you’d expect. Not something you’ll need constantly, but worth recognizing if you come across it.

A Gotcha: sort Fails On Mixed Types

msg: "{{ [3, 'apple', 1] | sort }}"

This fails — Jinja2 leans on Python’s own comparison rules underneath, and Python won’t compare a number and a string to decide which comes first. The error shows up the moment you try to sort a list with genuinely mixed types in it, not before.

The fix is to make sure a list is consistently typed before sorting it — if you’re not sure it is, convert explicitly first (| map('string'), covered in the next chapter, is one way to force everything to the same type before sorting), rather than assuming the data is clean.

Best Practices

  • Use + for list concatenation — it’s the one operator in this section that just works, with no conversion needed first.
  • Run unique before further processing whenever a list’s source might contain repeats you don’t want counted twice.
  • Check that a list is consistently typed before sorting it — a mixed-type list fails loudly, but only at the point you actually try to sort it.
  • Remember flatten fully flattens by default — reach for flatten(levels=N) the moment you need to preserve some of the original nesting.
Last updated on