Union, intersection and difference of lists

Starting with Ansible Core 2.16, the builtin filters ansible.builtin.union, ansible.builtin.intersect, ansible.builtin.difference and ansible.builtin.symmetric_difference began to behave differently and do no longer preserve the item order. Items in the resulting lists are returned in arbitrary order and the order can vary between subsequent runs.

The Ansible community.general collection provides the following additional list filters:

These filters preserve the item order, eliminate duplicates and are an extended version of the builtin ones, because they can operate on more than two lists.

Note

Stick to the builtin filters, when item order is not important or when you do not need the n-ary operating mode. The builtin filters are faster, because they rely mostly on sets as their underlying datastructure.

Let us use the lists below in the following examples:

A: [9, 5, 7, 1, 9, 4, 10, 5, 9, 7]
B: [4, 1, 2, 8, 3, 1, 7]
C: [10, 2, 1, 9, 1]

The union of A and B can be written as:

result: "{{ A | community.general.lists_union(B) }}"

This statement produces:

result: [9, 5, 7, 1, 4, 10, 2, 8, 3]

If you want to calculate the intersection of A, B and C, you can use the following statement:

result: "{{ A | community.general.lists_intersect(B, C) }}"

Alternatively, you can use a list of lists as an input of the filter

result: "{{ [A, B] | community.general.lists_intersect(C) }}"

or

result: "{{ [A, B, C] | community.general.lists_intersect(flatten=true) }}"

All three statements are equivalent and give:

result: [1]

Note

Be aware that in most cases, filter calls without any argument require flatten=true, otherwise the input is returned as result. The reason for this is, that the input is considered as a variable argument and is wrapped by an additional outer list. flatten=true ensures that this list is removed before the input is processed by the filter logic.

The filters ansplugin:community.general.lists_difference#filter or community.general.lists_symmetric_difference can be used in the same way as the filters in the examples above. They calculate the difference or the symmetric difference between two or more lists and preserve the item order.

For example, the symmetric difference of A, B and C may be written as:

result: "{{ A | community.general.lists_symmetric_difference(B, C) }}"

This gives:

result: [5, 8, 3, 1]