12

Is it possible to convert list of primitives to list of dicts using Jinja2 using list/map comprehensions?

Given this structure:

list:
  - some_val
  - some_val_2

Apply map on every element to obtain:

list:
  - statically_added: some_val
  - statically_added: some_val_2

It is possible other way around: list_from_example|map(attribute="statically_added")|list

lakier
  • 550
  • 4
  • 16

3 Answers3

2

I came up with the same question and found this solution:

- debug:
    msg: "{{ mylist | json_query('[].{\"statically_added\": @}') }}"
  vars:
    mylist:
      - some_val
      - some_val_2

Output:

ok: [localhost] => {
    "msg": [
        {
            "statically_added": "some_val"
        },
        {
            "statically_added": "some_val_2"
        }
    ]
}

Matthias Lohr
  • 1,696
  • 2
  • 20
  • 32
0

I ended up writing my own, tiny filter. I'm using Ansible, but I hope it's possible to adapt it for other environments as well.

For Ansible place this into file filter_plugins/singleton_dict.py:

class FilterModule(object):

    def filters(self):
        return {
            'singleton_dict':
                lambda element, key='singleton': {
                    key: element
                }
        }

Then [1, 2]|singleton_dict(key='name') produces [{'name': 1}, {'name': 2}]. When no key= is specified, it defaults to 'singleton'.

Petr
  • 62,528
  • 13
  • 153
  • 317
-2

It's actually pretty simple. At least, this works in Ansible:

vars:
  my_list:
    - some_val
    - some_val_2
  dict_keys:
    - key_1
    - key_2
tasks:
  - debug:
      msg: "{{ dict(dict_keys | zip(my_list)) }}"

Output:

TASK [debug] *******************************
ok: [localhost] => {
    "msg": {
        "key_1": "some_val",
        "key_2": "some_val_2"
    }

}

Note that you have to provide a list of keys, and they need to be distinct (the nature of dictionary implies that keys can't be the same).

UPDATE. Just realised that the title was a bit misleading, and I answered the title, not the actual question. However, I'm going to leave it as it is, because I believe many people will google for converting a list into a dictionary and find this post.

Vlad Nikiforov
  • 6,052
  • 1
  • 12
  • 18
  • What if the list is dynamic in size, and thus you need to generate dict_keys? (assume each key is the same) – Jonathan Oct 04 '19 at 23:52
  • 1
    Since this answer is for Ansible (but that's not the question's target) I'll reply to @Jonathan with what worked for me (assuming a list of string values, no special YAML characters in the list values, etc.) in Ansible: `input_list | map('regex_replace', '^(.*)$', 'static_key: "\1"') | map('from_yaml') | list` – William Price Mar 21 '20 at 06:12
  • 1
    This might not be answering the question correctly, but it answered my question that brought me here. Thanks! – John Ilacqua May 11 '23 at 03:52