mahen1812
mahen1812

Reputation: 31

Order of elements of dict objects of a list

I get the below lists from HOSTS:

"HOSTNAME": [
            "H1",
            "H2",
            "H3"
        ]

"SW_VERSION": [
            "7.2.2",
            "5.2.2",
            "6.2.2"
        ]

"OSPF_NEIGHBOR": [
            "10.1.1.1",
            "10.1.1.2",
            "10.1.1.3"
        ]

And I am converting them to List of Dict Objects as below: (objective is to create a report from the data that we get)

- set_fact:
    host_data: "{{ h_data|default([]) + [ { 'HOSTNAME': item.0, 'SW_VERSION': item.1, 'OSPF_NEIGHBOR': item.2} ] }}"
  with_together:
    - "{{ HOSTNAME }}"
    - "{{ SW_VERSION }}" 
    - "{{ OSPF_NEIGHBOR }}"

I get the output as below:

"host_data": [
    {
        "HOSTNAME": "H1",
        "OSPF_NEIGHBOR": "10.1.1.1",
        "SW_VERSION": "7.2.2"
    },
    {
        "HOSTNAME": "H2",
        "OSPF_NEIGHBOR": "10.1.1.2",
        "SW_VERSION": "6.2.2"
    },
    {
        "HOSTNAME": "H3",
        "OSPF_NEIGHBOR": "10.1.1.3",
        "SW_VERSION": "5.2.2"
    }
]

I gave HOSTNAME as item.0, SW_VERSION as item.1 and OSPF_NEIGHBOR as item.2, but in the output OSPF_NEIGHBOR comes second in the dict elements which affects the table format/column order.

How can we make sure the order is preserved?
Or Is there a way to re-arrange the dict elements order in the host_data list according to the required column order?

Screen-shot of the data conversion to a table

Upvotes: 3

Views: 354

Answers (1)

β.εηοιτ.βε
β.εηοιτ.βε

Reputation: 39159

I think this deserves an answer because it is not as simple as what @Zeitounator originally commented:

Dictionaries don't have order. Said differently you cannot rely on any order the data is spitted out from a dictionary. Use the key name that correspond to the information you need.

Actually, this is true up until Python 3.6, where a change as been made and:

New dict implementation

The dict type now uses a “compact” representation based on a proposal by Raymond Hettinger which was first implemented by PyPy. The memory usage of the new dict() is between 20% and 25% smaller compared to Python 3.5.

The order-preserving aspect of this new implementation is considered an implementation detail and should not be relied upon (this may change in the future, but it is desired to have this new dict implementation in the language for a few releases before changing the language spec to mandate order-preserving semantics for all current and future Python implementations; this also helps preserve backwards-compatibility with older versions of the language where random iteration order is still in effect, e.g. Python 3.5).

Source: https://docs.python.org/3/whatsnew/3.6.html#new-dict-implementation

Based on this, a change, that was originally added in the version 2.10 of Ansible: Add support for OrderedDict has been undone as the requirement to have Python 3.8 for Ansible was added.

Based on all this, my guess is you are on an old version of Ansible (prior to 2.10), and your solution should just be upgrading your Ansible version, also because the 2.9 branch has been out of support since 31 December 2021.

Upvotes: 3

Related Questions