1

I am trying to create a list of dictionaries in Ansible by parsing 2 lists and below is the code.

- name: Create list of data dictionary 
  vars:
     _sinfo: |-
       {% for data in data_list|default([]) %}
       {%- if item in data['subject'] %}
       [{ grade: {{data['grade']}}, id: {{data['id']}}, subject: {{data['subject']}} }]
       {%- endif -%}
       {% endfor %}
  set_fact:
    data_dict_list: "{{ data_dict_list|default([]) + _sinfo|list}}"
  with_items: 
    - "{{ subject_list }}"

Above script gives me a list of dictionary with each string broken into letters and using

data_dict_list: "{{ data_dict_list|default([]) + _sinfo|list|join}}"

Gives me error

msg: 'Unexpected templating type error occurred on ({{ data_dict_list|default([]) + _sinfo | list | join}}): can only concatenate list (not "unicode") to list'

List values: [u''Physics'', u''Chemistry'', u''Biology'', u''Math'', u''Geology'']

Inventory file:

data_list:
  - id: 31
    grade: ['A+']
    subject: Physics
  - id: 40
    grade: ['B']
    subject: Math
  - id: 30
    grade: ['A']
    subject: Biology
  - id: 33
    grade: ['A+']
    subject: Physics
  - id: 35
    grade: ['A+', 'B+']
    subject: Physics

Note:
Ansible version: 2.7.7
Python version: 2.7.18
Jinja2 version: 2.11.2

What I am trying to do is to group data by subject and create a list of subjects with each subject dictionary containing all the data with that subject.

β.εηοιτ.βε
  • 33,893
  • 13
  • 69
  • 83
moooni moon
  • 333
  • 1
  • 5
  • 19

1 Answers1

1

Q: "Group data by subject and create a list of subjects with each subject dictionary containing all the data with that subject"

A: The tasks below

    - set_fact:
        list_subj: "{{ list_subj|default([]) + [{item.0: item.1}] }}"
      loop: "{{ data_list|groupby('subject') }}"
    - debug:
        var: list_subj

give the list of the dictionaries

  list_subj:
  - Biology:
    - grade:
      - A
      id: 30
      subject: Biology
  - Math:
    - grade:
      - B
      id: 40
      subject: Math
  - Physics:
    - grade:
      - A+
      id: 31
      subject: Physics
    - grade:
      - A+
      id: 33
      subject: Physics
    - grade:
      - A+
      - B+
      id: 35
      subject: Physics

However, a dictionary might be more practical here. For example

    - set_fact:
        dict_subj: "{{ dict(data_list|groupby('subject')) }}"
    - debug:
        var: dict_subj

give

  dict_subj:
    Biology:
    - grade:
      - A
      id: 30
      subject: Biology
    Math:
    - grade:
      - B
      id: 40
      subject: Math
    Physics:
    - grade:
      - A+
      id: 31
      subject: Physics
    - grade:
      - A+
      id: 33
      subject: Physics
    - grade:
      - A+
      - B+
      id: 35
      subject: Physics
Vladimir Botka
  • 58,131
  • 4
  • 32
  • 63
  • Thanks but i still get the output with strings being broken down to individual characters. What does " [{item.0: item.1}] " do? – moooni moon Dec 02 '20 at 00:16
  • What's preventing you from taking a look at `- debug: msg: "{{ [{item.0: item.1}] }}"` in the loop? – Vladimir Botka Dec 02 '20 at 00:31
  • I am new to ansible so was not sure how you can debug within a loop but now i figured that out and thanks for the help. Using dictionary as you suggested worked better. – moooni moon Dec 02 '20 at 16:50