Ansible:使用 items2dict 将列表转换为字典

clo*_*ack 5 python ansible

给出以下列表:

fruits:
  - fruit: apple
    color: red
    texture: crunchy
    shape: round
  - fruit: grapefruit
    color: yellow
    taste: sour
  - fruit: pear
    color: yellow
Run Code Online (Sandbox Code Playgroud)

我将如何使用 items2dict 过滤器更改为字典(如下)?问题是存在多个且数量可变的值。

"{{ fruits | items2dict(key_name='fruit', value_name='??????') }}
Run Code Online (Sandbox Code Playgroud)

期望的结果:

fruits:
  - apple:
      color: red
      texture: crunchy
      shape: round
  - grapefruit:
      color: yellow
      taste: sour
  - pear:
      color: yellow
Run Code Online (Sandbox Code Playgroud)

我似乎找不到这里的方法:https ://docs.ansible.com/ansible/latest/user_guide/playbooks_filters.html#transforming-lists-into-dictionaries

Vla*_*tka 1

下面的任务可以完成这项工作

    - set_fact:
        fruits2: "{{ fruits2|default([]) + [{ item['fruit']: value }]}}"
      loop: "{{ fruits }}"
      vars:
        keys: "{{ item.keys()|difference(['fruit']) }}"
        vals: "{{ keys|map('extract', item)|list }}"
        value: "{{ dict(keys|zip(vals)) }}"
Run Code Online (Sandbox Code Playgroud)

给出

  fruits2:
  - apple:
      color: red
      shape: round
      texture: crunchy
  - grapefruit:
      color: yellow
      taste: sour
  - pear:
      color: yellow
Run Code Online (Sandbox Code Playgroud)

可以通过简单地将列表的串联更改为字典的组合来创建字典,而不是列表,例如

    - set_fact:
        fruits3: "{{ fruits3|default({})|combine({ item['fruit']: value }) }}"
      loop: "{{ fruits }}"
      vars:
        keys: "{{ item.keys()|difference(['fruit']) }}"
        vals: "{{ keys|map('extract', item)|list }}"
        value: "{{ dict(keys|zip(vals)) }}"
Run Code Online (Sandbox Code Playgroud)

给出

  fruits3:
    apple:
      color: red
      shape: round
      texture: crunchy
    grapefruit:
      color: yellow
      taste: sour
    pear:
      color: yellow
Run Code Online (Sandbox Code Playgroud)

items2dict只能用于选择 2 个属性(key_namevalue_name),例如

    - set_fact:
        fruits4: "{{ fruits|items2dict(key_name='fruit', value_name='color') }}"
Run Code Online (Sandbox Code Playgroud)

给出

  fruits4:
    apple: red
    grapefruit: yellow
    pear: yellow
Run Code Online (Sandbox Code Playgroud)

无法创建列表(所需结果)items2dictitems2dict返回一个字典。


items2dict如果缺少该属性,则会失败,例如

    - set_fact:
        fruits5: "{{ fruits|items2dict(key_name='fruit', value_name='taste') }}"
Run Code Online (Sandbox Code Playgroud)

失败

The error was: KeyError: 'taste'
Run Code Online (Sandbox Code Playgroud)