Home > Software engineering >  ansible - list of dictionaris to dictionary of list
ansible - list of dictionaris to dictionary of list

Time:10-21

I am trying to take a list of dict link the following:

family:
- {'name': 'lior', 'kidname': 'kid1'}
- {'name': 'lior', 'kidname': 'kid2'}
- {'name': 'lew', 'kidname': 'kid3'}
- {'name': 'lew', 'kidname': 'kid4'}

and turn it into a dict of list:

{
  'lior':['kid1', 'kid2']
  'lew':['kid3', 'kid4']
}

I need it as a set_fact command in an ansible playbook. so far I was able to create it, but with one kid only (the last one)

- set_fact:
    names: "{{ names | default({}) | combine({ item.name: [item.kidname] }) }}"
    with_items: "{{ family }}"

basically my problem is the add an empty list and append to it, like I did for the key.

Thank you, Lior

CodePudding user response:

You can use a defaultdict:

from collections import defaultdict

names = defaultdict(list)

for d in family:
    names[d['name']].append(d['kidname'])

output:

>>> names
defaultdict(list, {'lior': ['kid1', 'kid2'], 'lew': ['kid3', 'kid4']})

CodePudding user response:

I edited your initial attempt to append to the list

---

- hosts: localhost
  vars:
    family:
      - {'name': 'lior', 'kidname': 'kid1'}
      - {'name': 'lior', 'kidname': 'kid2'}
      - {'name': 'lew', 'kidname': 'kid3'}
      - {'name': 'lew', 'kidname': 'kid4'}
  tasks:
    - set_fact:
        names: "{{ names | default({}) | combine({ item.name: names[item.name] | default([])   [item.kidname] }) }}"
      with_items: "{{ family }}"

    - debug:
        var: names

Which outputs

TASK [debug] *******************************************************************
ok: [localhost] => {
    "names": {
        "lew": [
            "kid3",
            "kid4"
        ],
        "lior": [
            "kid1",
            "kid2"
        ]
    }
}
  • Related