[英]How to compare more than two lists have the same values in same indexes in Ansible?
我想比較兩個以上的列表,看看它們在相同的索引中是否具有相同的值。
我以前有關於如何在多個列表中交替值的問題。 這里基於此,我需要比較每個值並在值不相同時停止。 (可能有更好的解決方案,歡迎補充)
---
- name: data test
hosts: localhost
vars:
data_1: [True, False, True]
data_2: [False, True, True]
tasks:
- name: combine
set_fact:
comp_data: "{{ comp_data | default([]) + [item] }}"
loop:
- "{{ data_1 }}"
- "{{ data_2 }}"
- name: list all comp_data
debug:
msg: "{{ comp_data }}"
- name: zip
set_fact:
zip_data: "{{ lookup('together', *comp_data) }}"
- name: list all zip comp_data
debug:
msg: "{{ zip_data }}"
- name: check each element are identical
assert:
that:
- "{{ item | unique | length == 1 }}"
msg: |
"Data is not identical"
"{{ item }}"
loop: "{{ zip_data }}"
輸出:
TASK [check each element are identical] *************************************************************************************************************************************************
failed: [localhost] (item=[True, False]) => {
"ansible_loop_var": "item",
"assertion": false,
"changed": false,
"evaluated_to": false,
"item": [
true,
false
]
}
MSG:
"Data is not identical"
"[True, False]"
failed: [localhost] (item=[False, True]) => {
"ansible_loop_var": "item",
"assertion": false,
"changed": false,
"evaluated_to": false,
"item": [
false,
true
]
}
MSG:
"Data is not identical"
"[False, True]"
ok: [localhost] => (item=[True, True]) => {
"ansible_loop_var": "item",
"changed": false,
"item": [
true,
true
]
}
MSG:
All assertions passed
最后,它應該在看到不相同時立即停止,但它會迭代直到最后一個列表。
知道如何立即停止並更好地比較列表(如果有的話)嗎?
謝謝,
問: “一看到不一樣的東西就停下來。”
A:找到索引並對列表進行切片。 例如,給定數據
data_1: [True, False, True]
data_2: [False, True, True]
查找列表開始不同的索引
data_diff: "{{ data_1|zip(data_2)|
map('unique')|
map('length')|
map('log', 100)|map('round', 0, method='ceil')|map('int')|
list }}"
data_stop_index: |-
{% if 1 in data_diff %}{{ data_diff.index(1) }}
{% else %}{{ data_diff|length }}
{% endif %}
給
data_diff: [1, 1, 0]
data_stop_index: 0
然后,迭代
- debug:
msg: "{{ item|to_yaml }}"
with_together:
- "{{ data_1[:data_stop_index|int] }}"
- "{{ data_2[:data_stop_index|int] }}"
沒有結果,因為第一項不同
當你改變數據
data_1: [True, False, True]
data_2: [True, True, True]
上述任務將顯示第一項
msg: |-
[true, true]
可以修改代碼以處理更多列表。 例如,給定數據
data_1: [A, B, C]
data_2: [A, X, C]
data_3: [A, B, C]
壓縮並展平最多 100 個列表(如果需要更多,請增加對數底數)
data_diff: "{{ data_1|zip(data_2)|zip(data_3)|
map('flatten')|
map('unique')|
map('length')|
map('log', 100)|map('round', 0, method='ceil')|map('int')|
list }}"
data_stop_index: |-
{% if 1 in data_diff %}{{ data_diff.index(1) }}
{% else %}{{ data_diff|length }}
{% endif %}
給
data_diff: [0, 1, 0]
data_stop_index: 1
然后,將所有列表切片並迭代在一起
- debug:
msg: "{{ item|to_yaml }}"
with_together:
- "{{ data_1[:data_stop_index|int] }}"
- "{{ data_2[:data_stop_index|int] }}"
- "{{ data_3[:data_stop_index|int] }}"
給出第一個項目
msg: |-
[A, A, A]
(可選)創建自定義過濾器以比較列表中的項目
shell> cat filter_plugins/bool.py
def bool_gt(a, b):
return (a > b)
class FilterModule(object):
''' Ansible filters for operating on Boolean '''
def filters(self):
return {
'bool_gt': bool_gt,
}
然后,使用它代替笨拙的內置過濾器的管道( log、round、int )
data_diff: "{{ data_1|zip(data_2)|zip(data_3)|
map('flatten')|
map('unique')|
map('length')|
map('bool_gt', 1)|
list }}"
並擬合指數的計算
data_stop_index: |-
{% if true in data_diff %}
{{ data_diff.index(true) }}
{% else %}
{{ data_diff|length }}
{% endif %}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.