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.

4
  • _sinfo is not a list it is just a really big string, this is why running list on the string gives you a list of characters. Commented Dec 1, 2020 at 20:04
  • It is supposed to be a list with a single dictionary Commented Dec 1, 2020 at 20:07
  • It is just multiline string, see: stackoverflow.com/a/21699210/2123530 Commented Dec 1, 2020 at 21:00
  • Thanks @β.εηοιτ.βε It clarified few things. Commented Dec 2, 2020 at 16:51

1 Answer 1

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
Sign up to request clarification or add additional context in comments.

3 Comments

Thanks but i still get the output with strings being broken down to individual characters. What does " [{item.0: item.1}] " do?
What's preventing you from taking a look at - debug: msg: "{{ [{item.0: item.1}] }}" in the loop?
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.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.