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

3

我有两个字典:

source_list:
  myFlag1: true
  MyFlag2: false

还有第二个字典:

target_list:
  MyFlag1: false
  MyFlag2: false

键始终相同,但顺序尚不严格。 我该如何突出它们之间的差异? 我可以使用dict2items将列表转换为

source_list:
  - key: MyFlag1
    value: true
  - key: MyFlag2
    value: false

但我还是很困惑,如何比较它们... 当然,我可以循环两个字典并逐个比较,但这看起来不是很有效。

非常感谢您的帮助!

1个回答

8

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

答:给定简化的测试数据

    s:
      flag1: true
      Flag3: true
      flag2: false
    t:
      flag3: true
      flag1: false
      flag2: false
  • 比较变量,简要查找是否存在差异,例如:
    - debug:
        msg: The dictionaries are identical
      when: s == t
    - debug:
        msg: The dictionaries are different
      when: s != t

提供

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

测试 symmetric_difference 的长度。

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

提供

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

提供

  msg: flag1 is KO
  msg: flag2 is OK
  msg: flag3 is OK

问:如何突出它们之间的差异?

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

    - 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

提供

  diff_vals:
    flag1: true

Example of a complete playbook

- 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

弗拉基米尔,你的代码对我来说显示出错误。 “条件检查'source_list.keys()|symmetric_difference(target_list.keys())|length == 0'失败了。错误是:在({% if source_list.keys()|symmetric_difference(target_list.keys())|length == 0 %} True {% else %} False {% endif %})上发生了意外的模板化类型错误:不支持操作数类型为+:'dict_keys'和'dict_keys'。” - user41995
我使用Python3。解决方案是使用|list过滤器将由.keys()方法返回的dict_keys对象转换为简单的列表。 - user41995
非常感谢您,弗拉基米尔! - user41995

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接