'Ansible, create list of dictionaries from list of dictionaries, with specific subkey containing dictionary

I'm trying to create a list of dictionaries, from a list of dictionaries which contains a key with a dictionary as a value. So, I want a list of dictionaries each with the contents of that key.

Starting from:

  orig_dictionary:
    - key1:
        name: key1val_a
        extra_a: test
      key2:
        name: key2val_a
        extra_a: test
    - key1:
        name: key1val_a
      key2:
        name: key2val_a
    - key2:
        name: key2val_a
        extra_b: test

I'm tying to get,

  new_dictionary:
    - name: key2val_a
      extra_a: test
    - name: key2val_a
    - name: key2val_a
      extra_b: test

I've used map with an extract filter followed by the list filter, but I end up getting a string for some reason. Using jinja2 style filters, how can I do this?



Solution 1:[1]

If you want to get the last items from the dictionaries the task below

    - set_fact:
        new_dictionary: "{{ new_dictionary|d([]) + [item.0[item.1]] }}"
      with_together:
        - "{{ orig_dictionary }}"
        - "{{ orig_dictionary|map('last')|list }}"

gives the expected result

  new_dictionary:
  - extra_a: test
    name: key2val_a
  - name: key2val_a
  - extra_b: test
    name: key2val_a

Selecting the key2 attribute would be trivial. The task below gives the same result

    - set_fact:
        new_dictionary: "{{ orig_dictionary|map(attribute='key2')|list }}"

The module set_fact is not needed. Put the declaration of the variable new_dictionary where you want to. Optionally, you can use also Jinja to create the list, e.g.

    _new_dictionary: |
      {% for i in orig_dictionary %}
      - {{ i[i|last] }}
      {% endfor %}
    new_dictionary: "{{ _new_dictionary|from_yaml }}"

The order in Python dictionaries is a moving target. See for example Are dictionaries ordered in Python 3.6+?

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1