Looping thru a dictionary of dictionaries, then looping thru a list which is a value of a key in each item

So I have a var, which is a dict of dicts, with one of the values (“patchset_url_list”) being a list (possibly empty):

`

TASK [print out ‘cuda_versions’ var] ***************************************************************************************************************************************
ok: [localhost] => {
“cuda_versions”: {
“cuda_10_0”: {
“cuda_ver”: “10.0.130”,
“installer_url”: “https://developer.nvidia.com/compute/cuda/10.0/Prod/local_installers/cuda_10.0.130_410.48_linux”,
“min_driver_ver”: 410.48,
“patchset_url_list”: null
},
“cuda_8_0”: {
“cuda_ver”: “8.0.61”,
“installer_url”: “https://developer.nvidia.com/compute/cuda/8.0/Prod2/local_installers/cuda_8.0.61_375.26_linux-run”,
“min_driver_ver”: 375.26,
“patchset_url_list”: [
https://developer.nvidia.com/compute/cuda/8.0/Prod2/patches/2/cuda_8.0.61.2_linux-run
]
},
“cuda_9_0”: {
“cuda_ver”: “9.0.176”,
“installer_url”: “https://developer.nvidia.com/compute/cuda/9.0/Prod/local_installers/cuda_9.0.176_384.81_linux-run”,
“min_driver_ver”: 384.81,
“patchset_url_list”: [
https://developer.nvidia.com/compute/cuda/9.0/Prod/patches/1/cuda_9.0.176.1_linux-run”,
https://developer.nvidia.com/compute/cuda/9.0/Prod/patches/2/cuda_9.0.176.2_linux-run”,
https://developer.nvidia.com/compute/cuda/9.0/Prod/patches/3/cuda_9.0.176.3_linux-run”,
https://developer.nvidia.com/compute/cuda/9.0/Prod/patches/4/cuda_9.0.176.4_linux-run
]
},
“cuda_9_1”: {
“cuda_ver”: “9.1.85”,
“installer_url”: “https://developer.nvidia.com/compute/cuda/9.1/Prod/local_installers/cuda_9.1.85_387.26_linux”,
“min_driver_ver”: 387.26,
“patchset_url_list”: [
https://developer.nvidia.com/compute/cuda/9.1/Prod/patches/1/cuda_9.1.85.1_linux”,
https://developer.nvidia.com/compute/cuda/9.1/Prod/patches/2/cuda_9.1.85.2_linux”,
https://developer.nvidia.com/compute/cuda/9.1/Prod/patches/3/cuda_9.1.85.3_linux
]
},
“cuda_9_2”: {
“cuda_ver”: “9.2.148”,
“installer_url”: “https://developer.nvidia.com/compute/cuda/9.2/Prod2/local_installers/cuda_9.2.148_396.37_linux”,
“min_driver_ver”: 396.37,
“patchset_url_list”: [
https://developer.nvidia.com/compute/cuda/9.2/Prod2/patches/1/cuda_9.2.148.1_linux
]
}
}
}

`

I can get the individual scalar values of a key in each item when I loop thru the dict, as so:

`

  • name: Loop over versions, and show installer URL value for each item
    debug:
    msg: “Installer URL: {{ item.value.installer_url }}”
    loop: “{{ cuda_versions | dict2items }}”

(which gives me for example:)
“msg”: “Installer URL: https://developer.nvidia.com/compute/cuda/9.1/Prod/local_installers/cuda_9.1.85_387.26_linux

`

However, when I do that for the key “patchset_url_list” I of course get a list, as in this example:

`

“msg”: “Patch URL: [u’https://developer.nvidia.com/compute/cuda/9.1/Prod/patches/1/cuda_9.1.85.1_linux’, u’https://developer.nvidia.com/compute/cuda/9.1/Prod/patches/2/cuda_9.1.85.2_linux’, u’https://developer.nvidia.com/compute/cuda/9.1/Prod/patches/3/cuda_9.1.85.3_linux’]”

`

I cannot seem to figure out how to unroll the list, and take an action for each item in that list. I tried something like:

`

  • name: Loop over versions, and show patch URL value for each item
    debug:
    var: item
    loop: “{{ cuda_versions | dict2items | subelements(‘patchset_url_list’, skip_missing=True) }}”

`

…but I’m getting no output. How can I do this?

I think you can just use subelement directly without dict2items:
`
loop: “{{ cuda_versions | subelements(‘patchset_url_list’, ‘skip_missing=True’) }}”

`

Unfortunately not, tried that and got:

`

TASK [Loop over versions, and show patch URL value for each item] **********************************************************************************************************
fatal: [localhost]: FAILED! => {“msg”: “the key ‘patchset_url_list’ should point to a list, got None”}

`

It do require a list, but you empty patchset_url_list is not empty it's a list.
If you change it to a empty list instead of null it should work.

OK, my var now has a list value for every “patchset_url_list” value, as so:

`

TASK [print out ‘cuda_versions’ var] ***************************************************************************************************************************************
ok: [localhost] => {
“cuda_versions”: {
“cuda_10_0”: {
“cuda_ver”: “10.0.130”,
“installer_url”: “https://developer.nvidia.com/compute/cuda/10.0/Prod/local_installers/cuda_10.0.130_410.48_linux”,
“min_driver_ver”: 410.48,
“patchset_url_list”: [
null
]
},
“cuda_8_0”: {
“cuda_ver”: “8.0.61”,
“installer_url”: “https://developer.nvidia.com/compute/cuda/8.0/Prod2/local_installers/cuda_8.0.61_375.26_linux-run”,
“min_driver_ver”: 375.26,
“patchset_url_list”: [
https://developer.nvidia.com/compute/cuda/8.0/Prod2/patches/2/cuda_8.0.61.2_linux-run
]
},
“cuda_9_0”: {
“cuda_ver”: “9.0.176”,
“installer_url”: “https://developer.nvidia.com/compute/cuda/9.0/Prod/local_installers/cuda_9.0.176_384.81_linux-run”,
“min_driver_ver”: 384.81,
“patchset_url_list”: [
https://developer.nvidia.com/compute/cuda/9.0/Prod/patches/1/cuda_9.0.176.1_linux-run”,
https://developer.nvidia.com/compute/cuda/9.0/Prod/patches/2/cuda_9.0.176.2_linux-run”,
https://developer.nvidia.com/compute/cuda/9.0/Prod/patches/3/cuda_9.0.176.3_linux-run”,
https://developer.nvidia.com/compute/cuda/9.0/Prod/patches/4/cuda_9.0.176.4_linux-run
]
},
“cuda_9_1”: {
“cuda_ver”: “9.1.85”,
“installer_url”: “https://developer.nvidia.com/compute/cuda/9.1/Prod/local_installers/cuda_9.1.85_387.26_linux”,
“min_driver_ver”: 387.26,
“patchset_url_list”: [
https://developer.nvidia.com/compute/cuda/9.1/Prod/patches/1/cuda_9.1.85.1_linux”,
https://developer.nvidia.com/compute/cuda/9.1/Prod/patches/2/cuda_9.1.85.2_linux”,
https://developer.nvidia.com/compute/cuda/9.1/Prod/patches/3/cuda_9.1.85.3_linux
]
},
“cuda_9_2”: {
“cuda_ver”: “9.2.148”,
“installer_url”: “https://developer.nvidia.com/compute/cuda/9.2/Prod2/local_installers/cuda_9.2.148_396.37_linux”,
“min_driver_ver”: 396.37,
“patchset_url_list”: [
https://developer.nvidia.com/compute/cuda/9.2/Prod2/patches/1/cuda_9.2.148.1_linux
]
}
}
}

`

And now the play doesn’t error (yay) but I’m still not getting a single string value as I expect… I have in my playbook now:

`

  • name: Loop over versions, and show patch URL value for each item
    debug:
    msg: “Patch URL: {{ item }}”
    loop: “{{ cuda_versions | subelements(‘patchset_url_list’) }}”

`

But I am getting the following output (example for one item):

`

ok: [localhost] => (item=[{u’cuda_ver’: u’9.1.85’, u’min_driver_ver’: 387.26, u’patchset_url_list’: [u’https://developer.nvidia.com/compute/cuda/9.1/Prod/patches/1/cuda_9.1.85.1_linux’, u’https://developer.nvidia.com/compute/cuda/9.1/Prod/patches/2/cuda_9.1.85.2_linux’, u’https://developer.nvidia.com/compute/cuda/9.1/Prod/patches/3/cuda_9.1.85.3_linux’], u’installer_url’: u’https://developer.nvidia.com/compute/cuda/9.1/Prod/local_installers/cuda_9.1.85_387.26_linux’}, u’https://developer.nvidia.com/compute/cuda/9.1/Prod/patches/1/cuda_9.1.85.1_linux’]) => {
“msg”: “Patch URL: [{u’cuda_ver’: u’9.1.85’, u’min_driver_ver’: 387.26, u’patchset_url_list’: [u’https://developer.nvidia.com/compute/cuda/9.1/Prod/patches/1/cuda_9.1.85.1_linux’, u’https://developer.nvidia.com/compute/cuda/9.1/Prod/patches/2/cuda_9.1.85.2_linux’, u’https://developer.nvidia.com/compute/cuda/9.1/Prod/patches/3/cuda_9.1.85.3_linux’], u’installer_url’: u’https://developer.nvidia.com/compute/cuda/9.1/Prod/local_installers/cuda_9.1.85_387.26_linux’}, u’https://developer.nvidia.com/compute/cuda/9.1/Prod/patches/1/cuda_9.1.85.1_linux’]”
}
ok: [localhost] => (item=[{u’cuda_ver’: u’9.1.85’, u’min_driver_ver’: 387.26, u’patchset_url_list’: [u’https://developer.nvidia.com/compute/cuda/9.1/Prod/patches/1/cuda_9.1.85.1_linux’, u’https://developer.nvidia.com/compute/cuda/9.1/Prod/patches/2/cuda_9.1.85.2_linux’, u’https://developer.nvidia.com/compute/cuda/9.1/Prod/patches/3/cuda_9.1.85.3_linux’], u’installer_url’: u’https://developer.nvidia.com/compute/cuda/9.1/Prod/local_installers/cuda_9.1.85_387.26_linux’}, u’https://developer.nvidia.com/compute/cuda/9.1/Prod/patches/2/cuda_9.1.85.2_linux’]) => {
“msg”: “Patch URL: [{u’cuda_ver’: u’9.1.85’, u’min_driver_ver’: 387.26, u’patchset_url_list’: [u’https://developer.nvidia.com/compute/cuda/9.1/Prod/patches/1/cuda_9.1.85.1_linux’, u’https://developer.nvidia.com/compute/cuda/9.1/Prod/patches/2/cuda_9.1.85.2_linux’, u’https://developer.nvidia.com/compute/cuda/9.1/Prod/patches/3/cuda_9.1.85.3_linux’], u’installer_url’: u’https://developer.nvidia.com/compute/cuda/9.1/Prod/local_installers/cuda_9.1.85_387.26_linux’}, u’https://developer.nvidia.com/compute/cuda/9.1/Prod/patches/2/cuda_9.1.85.2_linux’]”
}
ok: [localhost] => (item=[{u’cuda_ver’: u’9.1.85’, u’min_driver_ver’: 387.26, u’patchset_url_list’: [u’https://developer.nvidia.com/compute/cuda/9.1/Prod/patches/1/cuda_9.1.85.1_linux’, u’https://developer.nvidia.com/compute/cuda/9.1/Prod/patches/2/cuda_9.1.85.2_linux’, u’https://developer.nvidia.com/compute/cuda/9.1/Prod/patches/3/cuda_9.1.85.3_linux’], u’installer_url’: u’https://developer.nvidia.com/compute/cuda/9.1/Prod/local_installers/cuda_9.1.85_387.26_linux’}, u’https://developer.nvidia.com/compute/cuda/9.1/Prod/patches/3/cuda_9.1.85.3_linux’]) => {
“msg”: “Patch URL: [{u’cuda_ver’: u’9.1.85’, u’min_driver_ver’: 387.26, u’patchset_url_list’: [u’https://developer.nvidia.com/compute/cuda/9.1/Prod/patches/1/cuda_9.1.85.1_linux’, u’https://developer.nvidia.com/compute/cuda/9.1/Prod/patches/2/cuda_9.1.85.2_linux’, u’https://developer.nvidia.com/compute/cuda/9.1/Prod/patches/3/cuda_9.1.85.3_linux’], u’installer_url’: u’https://developer.nvidia.com/compute/cuda/9.1/Prod/local_installers/cuda_9.1.85_387.26_linux’}, u’https://developer.nvidia.com/compute/cuda/9.1/Prod/patches/3/cuda_9.1.85.3_linux’]”
}

`

I really don't like the new loop syntax, the old one is better

  - name: Loop over versions, and show patch URL value for each item
    debug:
      msg: "Patch URL: {{ item.1 }}"
    with_subelements:
      - "{{ cuda_versions }}"
      - patchset_url_list

Then it's easy to remember that the fist one i item.0 (content of "{{ cuda_versions }}") and item.1 (content of patchset_url_list)

Right, came to that same conclusion after staring at the data for a bit … Thanks for the assist! :slight_smile: