# How to reformat a yaml dictionary?

**URL:** <https://forum.ansible.com/t/how-to-reformat-a-yaml-dictionary/24841>\
**Category:** Ansible Project\
**Created:** [June 28, 2017, 3:17pm UTC](https://forum.ansible.com/t/how-to-reformat-a-yaml-dictionary/24841 "2017-06-28T15:17:41Z")\
**Posts on this page:** 7\
**Page:** 1

<div class="post-metadata">

**Author:** ![j.r.hawkesworth](https://avatars.discourse-cdn.com/v4/letter/j/a3d4f5/32.png) [@j.r.hawkesworth](https://forum.ansible.com/u/j.r.hawkesworth)\
**Post date:** [June 28, 2017, 3:17pm UTC](https://forum.ansible.com/t/how-to-reformat-a-yaml-dictionary/24841/1 "2017-06-28T15:17:41Z")

</div>

Hello,

So I have a var dictionary which stores component groups and components

components\_by\_group:  
web:

- frontend\_app
- admin\_app  
database:
- db\_tools
- flyway

I’d like to invert this so that I can use the component to lookup the group

group\_by\_component:  
frontend\_app: web  
admin\_app: web  
db\_tools: database  
flyway: database

I can make a list of the groups easily enough…

- name: make a list of the groups  
set\_fact:  
component\_groups: “{{ component\_groups|default() + [item.key] }}”  
with\_dict: “{{ components\_by\_group }}”

How can I make a dict that looks like group\_by\_component above?

Many thanks,

Jon

---

<div class="post-metadata">

**Author:** ![j.r.hawkesworth](https://avatars.discourse-cdn.com/v4/letter/j/a3d4f5/32.png) [@j.r.hawkesworth](https://forum.ansible.com/u/j.r.hawkesworth)\
**Post date:** [June 30, 2017, 5:04pm UTC](https://forum.ansible.com/t/how-to-reformat-a-yaml-dictionary/24841/2 "2017-06-30T17:04:08Z")

</div>

I’m still bugged I can’t figure this out.

I can make a list of all components easily enough too

- name: make a list of the components  
set\_fact:  
components: “{{ components|default() |union( item.value) }}”  
with\_dict: “{{ components\_by\_group }}”

I haven’t figured a way to create more output key=value pairs than their are input items, so it would likely be useful to use the list of components in a with\_items. But then I am stuck trying to lookup the group that the component belongs to.

If you could pass a list as the second arg to with\_subelements that would let you loop through all the components in each of the groups and add them to an output, but with\_subelements only takes a string for its second arg.

I even wondered about using with\_cartesian on the components and groups lists and only adding to the output when group and component match components\_by\_group but I think you just get a single flat list with the cartesian product in it.

Any suggestions - devious or elegant - would be gratefully appreciated.

Jon

---

<div class="post-metadata">

**Author:** ![Daniel\_JD](https://avatars.discourse-cdn.com/v4/letter/d/f19dbf/32.png) [@Daniel\_JD](https://forum.ansible.com/u/Daniel_JD)\
**Post date:** [July 2, 2017, 6:03pm UTC](https://forum.ansible.com/t/how-to-reformat-a-yaml-dictionary/24841/3 "2017-07-02T18:03:32Z")

</div>

I couldnt get it to work with you variable. It is just bad formatted.

If you could format it like this it would be easy:

components\_by\_group:

- name: web  
components:
- frontend\_app
- admin\_app
- name: database  
components:
- db\_tools
- flyway

tasks:

- name: Change the format of the Group  
set\_fact:  
group\_by\_components: “{{ group\_by\_components | default(dict()) | combine({ item.1 : item.0.name }) }}”  
with\_subelements:
- “{{ components\_by\_group }}”
- components

Outputs:

ok: [localhost] =\> {  
“group\_by\_components”: {  
“admin\_app”: “web”,  
“db\_tools”: “database”,  
“flyway”: “database”,  
“frontend\_app”: “web”  
}  
}

---

<div class="post-metadata">

**Author:** ![j.r.hawkesworth](https://avatars.discourse-cdn.com/v4/letter/j/a3d4f5/32.png) [@j.r.hawkesworth](https://forum.ansible.com/u/j.r.hawkesworth)\
**Post date:** [July 3, 2017, 7:34am UTC](https://forum.ansible.com/t/how-to-reformat-a-yaml-dictionary/24841/4 "2017-07-03T07:34:31Z")

</div>

Thank you for this. It might well be easier for me to reformat the source variable.

The thing I want to avoid most of all is having to maintain two separate variables so the ability to transform from one to another at playbook runtime is the thing I need the most.

Jon

---

<div class="post-metadata">

**Author:** ![Pshem\_Kowalczyk](https://avatars.discourse-cdn.com/v4/letter/p/e480ec/32.png) [@Pshem\_Kowalczyk](https://forum.ansible.com/u/Pshem_Kowalczyk)\
**Post date:** [July 3, 2017, 9:22am UTC](https://forum.ansible.com/t/how-to-reformat-a-yaml-dictionary/24841/5 "2017-07-03T09:22:35Z")

</div>

Hi,

If you feel up to it - write a filter plugin. They’re quite easy to create. Have a look here for an example: [http://www.dasblinkenlichten.com/creating-ansible-filter-plugins/](http://www.dasblinkenlichten.com/creating-ansible-filter-plugins/)  
I use them when I have limited control over the data structure I have to deal with. Even if data manipulation can be done in ‘pure’ Ansible it ends up being quite convoluted (and usually spread across multiple files, since ‘include’ is the only way to have loop inside a loop whilst retaining full control over the data).

kind regards  
Pshem

---

<div class="post-metadata">

**Author:** ![Daniel\_JD](https://avatars.discourse-cdn.com/v4/letter/d/f19dbf/32.png) [@Daniel\_JD](https://forum.ansible.com/u/Daniel_JD)\
**Post date:** [July 3, 2017, 9:35am UTC](https://forum.ansible.com/t/how-to-reformat-a-yaml-dictionary/24841/6 "2017-07-03T09:35:30Z")

</div>

Lol, how cool is that!!! I never heard about it 😮

---

<div class="post-metadata">

**Author:** ![j.r.hawkesworth](https://avatars.discourse-cdn.com/v4/letter/j/a3d4f5/32.png) [@j.r.hawkesworth](https://forum.ansible.com/u/j.r.hawkesworth)\
**Post date:** [July 3, 2017, 1:22pm UTC](https://forum.ansible.com/t/how-to-reformat-a-yaml-dictionary/24841/7 "2017-07-03T13:22:13Z")

</div>

Thanks that’s a good idea. I’m struggling to come up with a good name for the filter though. I’ll think about it a bit more but best place to start almost seems to be extending with\_subelements so the second parameter can be a list (which would at least mean I don’t have to come up with a new filter name. I guess I could make something for internal use only, but would rather create something that I could contribute back to ansible.

Jon
