Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

Ansible – Replace values in a dictionary by looping through another dictionary

I have two dictionaries as below

"fictional_characters": {
   "male": [
      "Donkey",
      "Humpty",
      "Piranha"
   ],
   "female": [
      "Fiona",
      "Kitty_Softpaws",
      "Diane_Foxington"
   ]
}

And

"movie_names": {
   "Donkey": "Shrek",
   "Humpty": "Puss_in_Boots",
   "Piranha": "The_Bad_Guys",
   "Fiona": "Shrek",
   "Kitty_Softpaws": "Puss_in_Boots",
   "Diane_Foxingtin": "The_Bad_Guys"
}

I would like to change the dictionary values in "fictional_characters" to the values in "movie_names", e.g.

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

"fictional_characters": {
   "male": [
      "Shrek",
      "Puss_in_Boots",
      "The_Bad_Guys"
   ],
   "female": [
      "Shrek",
      "Puss_in_Boots",
      "The_Bad_Guys"
   ]
}

I started by converting the "fictional_characters" dictionary into a list

- name: Convert fictional_characters to a list
  set_fact:
    fictional_characters_list: "{{fictional_characters | dict2items }}"

That gave me

"fictional_characters_list": [
  {
    "key": "male",
    "value": [
      "Donkey",
      "Humpty",
      "Piranha"
    ],
  },
    "key": "female",
    "value": [
      "Fiona",
      "Kitty_Softpaws",
      "Diane_Foxington"
    ]
  }
]

Next, some Jinja

- name: Using Jinja to swap dict values
  set_fact:
    fict_char_movies: |
      {% for e in fictional_characters_list %}
      {{ e.key }}:
      {% for char in e.value %}
      {% if char in movie_names %}
        - {{ movie_names[char]|split(',') %}
      {% endif %}
      {% endfor %}
      {% endfor %}

- name: Print the result
  debug:
    msg: "{{ fict_char_movies | from_yaml }}"

the above returns the following result

"male": [
  [
    "Shrek"
  ],
  [
    "Puss_in_Boots"
  ],
  [
    "The_Bad_Guys"
  ],
"female": [
  [
    "Shrek"
  ],
  [
    "Puss_in_Boots"
  ],
  [
    "The_Bad_Guys"
  ]
]

How do I get rid of this nested list so that I get the below structure ?

"fictional_characters": {
   "male": [
      "Shrek",
      "Puss_in_Boots",
      "The_Bad_Guys"
   ],
   "female": [
      "Shrek",
      "Puss_in_Boots",
      "The_Bad_Guys"
   ]
}

>Solution :

The declarations below

  fict_char_movies_str: |
    {% for k,v in fictional_characters.items() %}
    {{ k }}:
    {% for char in v %}
    {% if char in movie_names %}
      - {{ movie_names[char] }}
    {% endif %}
    {% endfor %}
    {% endfor %}
  fict_char_movies: "{{ fict_char_movies_str|from_yaml }}"

The template can be simplified

    fict_char_movies_str: |
      {% for k,v in fictional_characters.items() %}
      {{ k }}:
        {{ v|map('extract', movie_names) }}
      {% endfor %}


give what you want

  fict_char_movies:
    female:
    - Shrek
    - Puss_in_Boots
    - The_Bad_Guys
    male:
    - Shrek
    - Puss_in_Boots
    - The_Bad_Guys

Example of a complete playbook for testing

- hosts: localhost

  vars:

    fictional_characters:
      female:
      - Fiona
      - Kitty_Softpaws
      - Diane_Foxington
      male:
      - Donkey
      - Humpty
      - Piranha

    movie_names:
      Diane_Foxington: The_Bad_Guys
      Donkey: Shrek
      Fiona: Shrek
      Humpty: Puss_in_Boots
      Kitty_Softpaws: Puss_in_Boots
      Piranha: The_Bad_Guys

    fict_char_movies_str: |
      {% for k,v in fictional_characters.items() %}
      {{ k }}:
      {% for char in v %}
      {% if char in movie_names %}
        - {{ movie_names[char] }}
      {% endif %}
      {% endfor %}
      {% endfor %}
    fict_char_movies: "{{ fict_char_movies_str|from_yaml }}"

  tasks:

    - debug:
        var: fict_char_movies

Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading