Ansible:使用公共键合并 2 个列表

Ansible: Merge 2 lists using common key

我有一个用例,我需要使用 Ansible 合并公共键名称上的 2 个列表。

列表 1:

 {
        "poc-cu2": [
            "40:A6:B7:5E:22:11",
            "40:A6:B7:5E:22:22"
        ],
        "test2211": [
            "40:A6:B7:5E:33:11",
            "40:A6:B7:5E:33:22"
        ],
        "test2244": [
            "40:A6:B7:5E:22:45",
            "40:A6:B7:5E:22:46"
        ]
    }

列表 2:

{
        "poc-cu2": [
            "root",
            "9WKA3KK3XN39",
            "9.3.13.44"
        ],
        "test2211": [
            "root2211",
            "221122112211",
            "9.3.13.82"
        ]
    }

预计:

列表 3:

{
        "poc-cu2": [
            "root",
            "9WKA3KK3XN39",
            "9.3.13.44",
            "40:A6:B7:5E:22:11",
            "40:A6:B7:5E:22:22"
        ],
        "test2211": [
            "root2211",
            "221122112211",
            "9.3.13.82",
            "40:A6:B7:5E:33:11",
            "40:A6:B7:5E:33:22"
        ]
    }

我了解了如何使用唯一键合并 2 个列表,但就我而言,我只需要在公共键上合并,请提出建议。

您可以使用 combine filter 获得您想要的大部分内容,如下所示:

- hosts: localhost
  gather_facts: false
  tasks:
    - set_fact:
        dict3: "{{ dict1|combine(dict2, list_merge='append') }}"

    - debug:
        var: dict3

这将产生:

TASK [debug] *******************************************************************
ok: [localhost] => {
    "dict3": {
        "poc-cu2": [
            "40:A6:B7:5E:22:11",
            "40:A6:B7:5E:22:22",
            "root",
            "9WKA3KK3XN39",
            "9.3.13.44"
        ],
        "test2211": [
            "40:A6:B7:5E:33:11",
            "40:A6:B7:5E:33:22",
            "root2211",
            "221122112211",
            "9.3.13.82"
        ],
        "test2244": [
            "40:A6:B7:5E:22:45",
            "40:A6:B7:5E:22:46"
        ]
    }
}

如果你希望最终结果只包含两者共有的键 字典有点棘手,但这似乎有效:

- hosts: localhost
  gather_facts: false
  tasks:
    - set_fact:
        dict3: "{{ dict3|combine({item: dict1[item] + dict2[item]}) }}"
      when: item in dict2
      loop: "{{ dict1.keys() }}"
      vars:
        dict3: {}

    - debug:
        var: dict3

产生:

TASK [debug] *******************************************************************
ok: [localhost] => {
    "dict3": {
        "poc-cu2": [
            "40:A6:B7:5E:22:11",
            "40:A6:B7:5E:22:22",
            "root",
            "9WKA3KK3XN39",
            "9.3.13.44"
        ],
        "test2211": [
            "40:A6:B7:5E:33:11",
            "40:A6:B7:5E:33:22",
            "root2211",
            "221122112211",
            "9.3.13.82"
        ]
    }
}

以上通过迭代 dict1 中的键来工作,并且对于每个 来自 dict1 的密钥也存在于 dict2,我们合成一个新的 包含 dict1dict2 的相应值的字典,然后使用 combine 过滤器将其合并到我们最终的字典中。

给定数据

    dict1:
      poc-cu2:
        - 40:A6:B7:5E:22:11
        - 40:A6:B7:5E:22:22
      test2211:
        - 40:A6:B7:5E:33:11
        - 40:A6:B7:5E:33:22
      test2244:
        - 40:A6:B7:5E:22:45
        - 40:A6:B7:5E:22:46

    dict2:
      poc-cu2:
        - root
        - 9WKA3KK3XN39
        - 9.3.13.44
      test2211:
        - root2211
        - '221122112211'
        - 9.3.13.82

不需要迭代。将声明放在下面 appropriate。字典 dict_cmn 保留了 dict1dict2[=14= 的合并公共属性]

dict_1_2: "{{ dict1|combine(dict2, list_merge='append') }}"
keys_cmn: "{{ dict1.keys()|intersect(dict2.keys()) }}"
vals_cmn: "{{ keys_cmn|map('extract', dict_1_2) }}"
dict_cmn: "{{ dict(keys_cmn|zip(vals_cmn)) }}"

给予

  dict_1_2:
    poc-cu2:
    - 40:A6:B7:5E:22:11
    - 40:A6:B7:5E:22:22
    - root
    - 9WKA3KK3XN39
    - 9.3.13.44
    test2211:
    - 40:A6:B7:5E:33:11
    - 40:A6:B7:5E:33:22
    - root2211
    - '221122112211'
    - 9.3.13.82
    test2244:
    - 40:A6:B7:5E:22:45
    - 40:A6:B7:5E:22:46

  keys_cmn:
  - poc-cu2
  - test2211

  vals_cmn:
  - - 40:A6:B7:5E:22:11
    - 40:A6:B7:5E:22:22
    - root
    - 9WKA3KK3XN39
    - 9.3.13.44
  - - 40:A6:B7:5E:33:11
    - 40:A6:B7:5E:33:22
    - root2211
    - '221122112211'
    - 9.3.13.82

  dict_cmn:
    poc-cu2:
    - 40:A6:B7:5E:22:11
    - 40:A6:B7:5E:22:22
    - root
    - 9WKA3KK3XN39
    - 9.3.13.44
    test2211:
    - 40:A6:B7:5E:33:11
    - 40:A6:B7:5E:33:22
    - root2211
    - '221122112211'
    - 9.3.13.82