Ansible - 如何比较两个具有相同键的字典

use*_*995 3 dictionary compare ansible

我有两本词典:

source_list:
  myFlag1: true
  MyFlag2: false
Run Code Online (Sandbox Code Playgroud)

第二个字典:

target_list:
  MyFlag1: false
  MyFlag2: false
Run Code Online (Sandbox Code Playgroud)

密钥始终相同,但顺序尚不严格。我怎样才能突出它们之间的区别?我可以使用 dict2items 将列表转换为

source_list:
  - key: MyFlag1
    value: true
  - key: MyFlag2
    value: false
Run Code Online (Sandbox Code Playgroud)

但我又很困惑,我怎样才能比较它们......当然,我可以循环两个字典并一一比较,但它看起来并不真正有效。任何帮助将不胜感激!

Vla*_*tka 8

问:“如何比较两个具有相同键的字典?”

A:给出测试的简化数据

    s:
      flag1: true
      Flag3: true
      flag2: false
    t:
      flag3: true
      flag1: false
      flag2: false
Run Code Online (Sandbox Code Playgroud)
  • 比较变量以简要找出是否存在差异,例如
    - debug:
        msg: The dictionaries are identical
      when: s == t
    - debug:
        msg: The dictionaries are different
      when: s != t
Run Code Online (Sandbox Code Playgroud)

给出

  msg: The dictionaries are different
Run Code Online (Sandbox Code Playgroud)
  • 接下来,比较键,例如声明变量
    s_keys: "{{ s.keys()|list }}"
    t_keys: "{{ t.keys()|list }}"
    diff_keys: "{{ s_keys|symmetric_difference(t_keys) }}"
Run Code Online (Sandbox Code Playgroud)

并测试symmetry_difference的长度

    - debug:
        msg: "The difference in the keys: {{ diff_keys }}"
      when:  diff_keys|length != 0
Run Code Online (Sandbox Code Playgroud)

给出

  msg: 'The difference in the keys: [''Flag3'', ''flag3'']'
Run Code Online (Sandbox Code Playgroud)
  • 让我们假设字典具有相同的键来查找不同的值,例如
    s:
      flag1: true
      flag3: true
      flag2: false
    t:
      flag3: true
      flag1: false
      flag2: false
Run Code Online (Sandbox Code Playgroud)
  • 迭代键列表并逐项比较字典,例如
    - debug:
        msg: "{{ item }} is {{ (s[item] == t[item])|ternary('OK', 'KO') }}"
      loop: "{{ s.keys()|sort }}"
      when:  diff_keys|length == 0
Run Code Online (Sandbox Code Playgroud)

给出

  msg: flag1 is KO
  msg: flag2 is OK
  msg: flag3 is OK
Run Code Online (Sandbox Code Playgroud)

问:“我怎样才能突出它们之间的区别?”

A:创建一个仅包含不同值的字典,例如

    - set_fact:
        diff_vals: "{{ diff_vals|d({})|combine({item: s[item]}) }}"
      loop: "{{ s.keys()|sort }}"
      when:
        - diff_keys|length == 0
        - s[item] != t[item]
    - debug:
        var: diff_vals
Run Code Online (Sandbox Code Playgroud)

给出

  diff_vals:
    flag1: true
Run Code Online (Sandbox Code Playgroud)

完整剧本示例

- hosts: localhost
  gather_facts: false

  vars:
    s:
      flag1: true
      flag3: true
      flag2: false
    t:
      flag3: true
      flag1: false
      flag2: false
    
    s_keys: "{{ s.keys()|list }}"
    t_keys: "{{ t.keys()|list }}"
    diff_keys: "{{ s_keys|symmetric_difference(t_keys) }}"

  tasks:

    - debug:
        msg: The dictionaries are identical
      when: s == t
    - debug:
        msg: The dictionaries are different
      when: s != t

    - debug:
        msg: "The difference in the keys: {{ diff_keys }}"
      when:  diff_keys|length != 0

    - debug:
        msg: "{{ item }} is {{ (s[item] == t[item])|ternary('OK', 'KO') }}"
      loop: "{{ s.keys()|sort }}"
      when:  diff_keys|length == 0

    - set_fact:
        diff_vals: "{{ diff_vals|d({})|combine({item: s[item]}) }}"
      loop: "{{ s.keys()|sort }}"
      when:
        - diff_keys|length == 0
        - s[item] != t[item]
    - debug:
        var: diff_vals
Run Code Online (Sandbox Code Playgroud)