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.
"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