てくなべ

インフラ、ネットワーク、自動化などの技術的なことを書いていきます。

Ansible のフィルターでリストから組み合わせを生成する(combinations, zip, zip_longest)

f:id:akira6592:20170604104846p:plain

■ はじめに

Ansible 2.3 でCombination Filters というリストの組み合わせを生成するフィルターが追加されました。 公式ドキュメントに使用例が載っていますが、いくつか実際に試してみて出力結果を含めて確認します。

Filters — Ansible Documentation

■ combinations で組み合わせを生成する

1つのリストを元に組み合わせを生成します。

使い方

例:リスト[1,2,3,4,5] から2つ選ぶ組み合わせを生成する

- name: give me combinations for sets of 2
  debug: msg="{{ [1,2,3,4,5]|combinations(2)|list }}"

実行結果

"msg": [
    [
        1,
        2
    ],
    [
        1,
        3
    ],
    [
        1,
        4
    ],
    [
        1,
        5
    ],
    [
        2,
        3
    ],
    [
        2,
        4
    ],
    [
        2,
        5
    ],
    [
        3,
        4
    ],
    [
        3,
        5
    ],
    [
        4,
        5
    ]
]

■ zip でリストを統合する

Pythonzip 関数のように、リストから組み合わせを生成します。 2つのリストの長さが異なる場合は、短いほうに合わせられます。

使い方

例:2つのリストが統合する

- name: give me shortest combo of 2 lists
  debug: msg="{{ [1,2,3]|zip(['a','b','c','d','e','f'])|list }}"

実行結果

"msg": [
    [
        1,
        "a"
    ],
    [
        2,
        "b"
    ],
    [
        3,
        "c"
    ]
]

■ zip_longest でリストを統合する

Pythonzip_longest関数のように、リストから組み合わせを生成します。 前述の zip とは異なり、2つのリストの長さが異なる場合は、長いほうに合わせられます。 足りない部分はfillvalueで指定したもので補完されます。

使い方

例:3つのリストを統合し、足りない部分は 'X' で補完する

- name: give me longest combo of 3 lists , fill with X
  debug: msg="{{ [1,2,3]|zip_longest(['a','b','c','d','e','f'], [21, 22, 23], fillvalue='X')|list }}"

実行結果

"msg": [
    [
        1,
        "a",
        21
    ],
    [
        2,
        "b",
        22
    ],
    [
        3,
        "c",
        23
    ],
    [
        "X",
        "d",
        "X"
    ],
    [
        "X",
        "e",
        "X"
    ],
    [
        "X",
        "f",
        "X"
    ]
]

■ さいごに

他の方法で代替できるケースもありそうですが、複雑になる場合はこれらのフィルターを利用するのが便利そうです。

以上です。