压缩列表和字典的oneliner

时间:2019-07-29 00:38:15

标签: ansible

1个列表作为键,其他整个列表作为字典中每个键的值

我正在使用Ansible 2.7

我有以下两个列表。

list1:
  -  l1
  -  l2
  -  l3
  -  l4
  -  l5
  -  l6

list2:
  -  L1
  -  L2

当我使用"{{dict(list1 | zip(list2))}}"时 我得到以下输出

l1: L1
l2: L2

但是我希望在Ansible中使用单个衬纸获得以下输出。

l1: [L1, L2]
l2: [L1, L2]
l3: [L1, L2]
l4: [L1, L2]
l5: [L1, L2]
l6: [L1, L2]

有人可以帮我帮忙吗?

2 个答案:

答案 0 :(得分:0)

对我来说,这就像一个难题。 认为我为此找到了一线。 也许有人会有更好的建议!

"{{ dict(list1 | zip_longest([list2], fillvalue=list2)) }}"

说明

这个想法是使用zip来压缩第一个列表(list1),其中listlist2[list2])。因此,ziplist1list2聚合在一起,而不是占用list2的每个元素。
但是在这种情况下,您将以一个好项目结束,而另一个将是不正确的,因为列表(显然)不是相同大小(第二个大小为一个)。在这种情况下,解决方案是使用zip_longest代替zip,以便在没有更多要压缩的元素时使用list2。查看this文档以获取有关Ansible过滤器的信息。

完整剧本

---
- name: Oneliner for zippping list and dict
  hosts: localhost
  connection: local
  gather_facts: no
  vars:
    list1:
      -  l1
      -  l2
      -  l3
      -  l4
      -  l5
      -  l6
    list2:
      -  L1
      -  L2

  tasks:
    - name: Perform a command that will not be understood without a good comment ...
      set_fact:
        result: "{{ dict(list1 | zip_longest([list2], fillvalue=list2)) }}"
    - name: Print result
      debug:
        var: result

# ok: [localhost] => {
#     "result": {
#         "l1": [
#             "L1",
#             "L2"
#         ],
#         "l2": [
#             "L1",
#             "L2"
#         ],
# [...]

免责声明

我不确定使用它是否是一个好主意。我将更喜欢一种更明确,更标准的方式,就像@Matt P提出的答案一样。

答案 1 :(得分:-1)

为什么必须是单线?这将实现您想要的结果:

    - set_fact:
        new_dict: {}

    - set_fact:
        new_dict: "{{ new_dict | combine({item: list2}) }}"
      loop: "{{ list1 }}"