cancel
Showing results for 
Search instead for 
Did you mean: 
cancel
3458
Views
10
Helpful
4
Replies

cdp json-pretty iterate help

Esmogyi
Level 1
Level 1

on several nexus switches, I run the command: Show cdp neighbors detail | json-pretty

I want to iterate through it to grab "device_id", "v4addr", "platform_id", "intf_id", and "port_id" but I'm struggling on the way its been formatted.

 

Why is it {"table": {"row": [{ "key":"value", "key":"value", "key":"value", "capability": ["router", "switch"], "key":"value"}] }} and how do I iterate through a table, row, and the extra capability list/dict thing? 

 

I tried:

import json

objectJson = {
    "TABLE_cdp_neighbor_detail_info": {
        "ROW_cdp_neighbor_detail_info": [
            {
                "ifindex": "824352435",
                "device_id": "mynexuscore-2",
                "sysname": "dc-core2",
                "numaddr": "1",
                "v4addr": "10.128.1.5",
                "platform_id": "N9K-C9372PX",
                "capability": [
                    "router",
                    "switch",
                    "Supports-STP-Dispute"
                ],
                "intf_id": "mgmt0",
                "port_id": "mgmt0",
                "ttl": "156",
                "version": "Cisco Nexus Operating System (NX-OS) Software, Version 7.0(3)I4(8a)",
                "version_no": "v2",
                "duplexmode": "full",
                "mtu": "1500",
                "syslocation": "snmplocation",
                "num_mgmtaddr": "1",
                "v4mgmtaddr": "10.128.1.5"
            },
            {
                "ifindex": "436207616",
                "device_id": "tracer-01",
                "numaddr": "2",
                "v4addr": [
                    "192.168.254.50",
                    "192.168.5.50"
                ],
                "platform_id": "N3000",
                "capability": "router",
                "intf_id": "Ethernet1/1",
                "port_id": "Te3/0/1",
                "ttl": "153",
                "version": "6.5.2.5",
                "version_no": "v2",
                "nativevlan": "250",
                "mtu": "0",
                "num_mgmtaddr": "0"
            },
            {
                "ifindex": "4362246246",
                "device_id": "mynexuscore-2Standby",
                "numaddr": "2",
                "v4addr": "10.128.1.15",
                "v6addr": "fe80::5a97:bdff:bbbb:aaaa",
                "platform_id": "AIR-CT5520-K9",
                "capability": "host",
                "intf_id": "Ethernet1/3",
                "port_id": "TenGigabitEthernet0/0/1",
                "ttl": "125",
                "version": "Manufacturer's Name: Cisco Systems Inc.  Product Name: Cisco Controller  Product Version: 8.5.171.0  RTOS Version: 8.5.171.0  Bootloader Version: 8.1.102.0  Build Type: DATA + WPS",
                "version_no": "v2",
                "duplexmode": "full",
                "mtu": "0",
                "num_mgmtaddr": "0"
            },
            {
                "ifindex": "436209152",
                "device_id": "WLC-1",
                "numaddr": "2",
                "v4addr": "10.128.1.16",
                "v6addr": "fe80::72e4:22ff:bbbb:aaaa",
                "platform_id": "AIR-CT5520-K9",
                "capability": "host",
                "intf_id": "Ethernet1/4",
                "port_id": "TenGigabitEthernet0/0/1",
                "ttl": "158",
                "version": "Manufacturer's Name: Cisco Systems Inc.  Product Name: Cisco Controller  Product Version:8.5.171.0  RTOS Version: 8.5.171.0  Bootloader Version: 8.1.102.0  Build Type: DATA + WPS",
                "version_no": "v2",
                "duplexmode": "full",
                "mtu": "0",
                "num_mgmtaddr": "0"
            },
            {
                "ifindex": "436205555",
                "device_id": "MDF-1",
                "vtpname": "thisguy",
                "numaddr": "1",
                "v4addr": "10.128.1.18",
                "platform_id": "cisco WS-C2960X-48FPD-L",
                "capability": [
                    "switch",
                    "IGMP_cnd_filtering"
                ],
                "intf_id": "Ethernet1/5",
                "port_id": "TenGigabitEthernet1/0/1",
                "ttl": "165",
                "version": "Cisco IOS Software, C2960X Software (C2960X-UNIVERSALK9-M), Version 15.2(2)E3, RELEASE SOFTWARE (fc3)\nTechnical Support: http://www.cisco.com/techsupport\nCopyright (c) 1986-2015 by Cisco Systems, Inc.\nCompiled Wed 26-Aug-15 07:12 by prod_rel_team",
                "version_no": "v2",
                "nativevlan": "1",
                "duplexmode": "full",
                "mtu": "0",
                "num_mgmtaddr": "1",
                "v4mgmtaddr": "10.128.1.13"
            }
        ]
    }
}


dictionary = json.dumps(objectJson)

print("before loop")

for key in dictionary:
    if key == "device_id":
        print (key)
        Print("key loop")

print("after loop)")

 

Note: this is not the original attempt. I've built some full stack web apps before using flask and javascript but this has been more frustrating to navigate through than any of that. 

 

 

I cant even get the device_id to print for each device.

1 Accepted Solution

Accepted Solutions

HI @Esmogyi 

Your outermost object is a dictionary and then within those top level key/value pairs you have strings and lists of dictionaries. 

Wrapping your head around these complex data structures made my head hurt but once you get it its amazing what you can do.

 

Not sure if this will help:
https://gratuitous-arp.net/decomposing-complex-json-data-structures/

 

One tip is to start at the top level and sort of peel the layers back.  I know from the first character "{" that I have a dictionary 

You can break out key/value pairs but a good shortcut with some of these complex structures is to look at the keys.

>>> print(objectJson.keys())
dict_keys(['TABLE_cdp_neighbor_detail_info'])
>>>

This is a dictionary with on key so I know the good stuff is at least one level deep.

 

Key/value break out if you have more than one key can be helpful.  Notice I want the key and then what type of object it has for a value.

>>> for key, value in objectJson.items():
...   print(f"key: {key} \t val: {type(value)}")
...
key: TABLE_cdp_neighbor_detail_info 	 val: <class 'dict'>
>>>

going to the next level:

>>> for key, value in objectJson['TABLE_cdp_neighbor_detail_info'].items():
...   print(f"key: {key} \t val: {type(value)}")
...
key: ROW_cdp_neighbor_detail_info 	 val: <class 'list'>

OK..now I have one more key and then I probably have the stuff I care about.

 

I now know that this structure is a list.  

objectJson['TABLE_cdp_neighbor_detail_info']['ROW_cdp_neighbor_detail_info']

Lets see how many rows we have:

 

print(len(objectJson['TABLE_cdp_neighbor_detail_info']['ROW_cdp_neighbor_detail_info']))
5

Sometimes its easier to put that long thing that is a list into a new variable as you can see below I put into "results_list" and then I iterate over results list.

 

>>> results_list = objectJson['TABLE_cdp_neighbor_detail_info']['ROW_cdp_neighbor_detail_info']
>>> for row in results_list: ... print(row) ... print() ... {'ifindex': '824352435', 'device_id': 'mynexuscore-2', 'sysname': 'dc-core2', 'numaddr': '1', 'v4addr': '10.128.1.5', 'platform_id': 'N9K-C9372PX', 'capability': ['router', 'switch', 'Supports-STP-Dispute'], 'intf_id': 'mgmt0', 'port_id': 'mgmt0', 'ttl': '156', 'version': 'Cisco Nexus Operating System (NX-OS) Software, Version 7.0(3)I4(8a)', 'version_no': 'v2', 'duplexmode': 'full', 'mtu': '1500', 'syslocation': 'snmplocation', 'num_mgmtaddr': '1', 'v4mgmtaddr': '10.128.1.5'} {'ifindex': '436207616', 'device_id': 'tracer-01', 'numaddr': '2', 'v4addr': ['192.168.254.50', '192.168.5.50'], 'platform_id': 'N3000', 'capability': 'router', 'intf_id': 'Ethernet1/1', 'port_id': 'Te3/0/1', 'ttl': '153', 'version': '6.5.2.5', 'version_no': 'v2', 'nativevlan': '250', 'mtu': '0', 'num_mgmtaddr': '0'} {'ifindex': '4362246246', 'device_id': 'mynexuscore-2Standby', 'numaddr': '2', 'v4addr': '10.128.1.15', 'v6addr': 'fe80::5a97:bdff:bbbb:aaaa', 'platform_id': 'AIR-CT5520-K9', 'capability': 'host', 'intf_id': 'Ethernet1/3', 'port_id': 'TenGigabitEthernet0/0/1', 'ttl': '125', 'version': "Manufacturer's Name: Cisco Systems Inc. Product Name: Cisco Controller Product Version: 8.5.171.0 RTOS Version: 8.5.171.0 Bootloader Version: 8.1.102.0 Build Type: DATA + WPS", 'version_no': 'v2', 'duplexmode': 'full', 'mtu': '0', 'num_mgmtaddr': '0'} {'ifindex': '436209152', 'device_id': 'WLC-1', 'numaddr': '2', 'v4addr': '10.128.1.16', 'v6addr': 'fe80::72e4:22ff:bbbb:aaaa', 'platform_id': 'AIR-CT5520-K9', 'capability': 'host', 'intf_id': 'Ethernet1/4', 'port_id': 'TenGigabitEthernet0/0/1', 'ttl': '158', 'version': "Manufacturer's Name: Cisco Systems Inc. Product Name: Cisco Controller Product Version:8.5.171.0 RTOS Version: 8.5.171.0 Bootloader Version: 8.1.102.0 Build Type: DATA + WPS", 'version_no': 'v2', 'duplexmode': 'full', 'mtu': '0', 'num_mgmtaddr': '0'} {'ifindex': '436205555', 'device_id': 'MDF-1', 'vtpname': 'thisguy', 'numaddr': '1', 'v4addr': '10.128.1.18', 'platform_id': 'cisco WS-C2960X-48FPD-L', 'capability': ['switch', 'IGMP_cnd_filtering'], 'intf_id': 'Ethernet1/5', 'port_id': 'TenGigabitEthernet1/0/1', 'ttl': '165', 'version': 'Cisco IOS Software, C2960X Software (C2960X-UNIVERSALK9-M), Version 15.2(2)E3, RELEASE SOFTWARE (fc3)\nTechnical Support: http://www.cisco.com/techsupport\nCopyright (c) 1986-2015 by Cisco Systems, Inc.\nCompiled Wed 26-Aug-15 07:12 by prod_rel_team', 'version_no': 'v2', 'nativevlan': '1', 'duplexmode': 'full', 'mtu': '0', 'num_mgmtaddr': '1', 'v4mgmtaddr': '10.128.1.13'} >>>

Now you can see that each row in the list is a dictionary.  Well we know how to process that now.

Lest look at the keys we have available to us

 

>>> for row in results_list:
...   print(row.keys())
...
dict_keys(['ifindex', 'device_id', 'sysname', 'numaddr', 'v4addr', 'platform_id', 'capability', 'intf_id', 'port_id', 'ttl', 'version', 'version_no', 'duplexmode', 'mtu', 'syslocation', 'num_mgmtaddr', 'v4mgmtaddr'])
dict_keys(['ifindex', 'device_id', 'numaddr', 'v4addr', 'platform_id', 'capability', 'intf_id', 'port_id', 'ttl', 'version', 'version_no', 'nativevlan', 'mtu', 'num_mgmtaddr'])
dict_keys(['ifindex', 'device_id', 'numaddr', 'v4addr', 'v6addr', 'platform_id', 'capability', 'intf_id', 'port_id', 'ttl', 'version', 'version_no', 'duplexmode', 'mtu', 'num_mgmtaddr'])
dict_keys(['ifindex', 'device_id', 'numaddr', 'v4addr', 'v6addr', 'platform_id', 'capability', 'intf_id', 'port_id', 'ttl', 'version', 'version_no', 'duplexmode', 'mtu', 'num_mgmtaddr'])
dict_keys(['ifindex', 'device_id', 'vtpname', 'numaddr', 'v4addr', 'platform_id', 'capability', 'intf_id', 'port_id', 'ttl', 'version', 'version_no', 'nativevlan', 'duplexmode', 'mtu', 'num_mgmtaddr', 'v4mgmtaddr'])
>>>

 OK lets say I want platform and v4IP:

>>> for row in results_list:
...   print(f"Platform: {row['platform_id']} IP: {row['v4addr']}")
...
Platform: N9K-C9372PX IP: 10.128.1.5
Platform: N3000 IP: ['192.168.254.50', '192.168.5.50']
Platform: AIR-CT5520-K9 IP: 10.128.1.15
Platform: AIR-CT5520-K9 IP: 10.128.1.16
Platform: cisco WS-C2960X-48FPD-L IP: 10.128.1.18
>>>

With all of this you can now see that some of the values are lists (devices with multiple IPs) so one more step to iterate over those if you need to.

 

Spend some time working through these exercises yourself.  Knowing how to deal with these complex structures will serve you well!



errors:

  1. for key, value in objectJson['TABLE_cdp_neighbor_detail_info']['ROW_cdp_neighbor_detail_info']:
    ValueError: too many values to unpack (expected 2)

    Here you are trying to treat a list like a dictionary, hence the "too many values to unpack" error.  Normally when I get this error I've forgotten to use  .items() in my for statement.

  2. for key, value in objectJson.items(['TABLE_cdp_neighbor_detail_info']['ROW_cdp_neighbor_detail_info']):
    TypeError: list indices must be integers or slices, not str

    I don't believe you can pass the .items() iterator an argument. Normally the use is:
    for key, val in dict_object.items()
    that "unpacks" the key value pair and puts the key in they "key" variable and whatever the value is in the "val" variable.    
    the error tells you that you are basically not treating a list as a list.

 

  1. for key, value in objectJson['TABLE_cdp_neighbor_detail_info']['ROW_cdp_neighbor_detail_info']:
    ValueError: too many values to unpack (expected 2)

this is like the first example.

View solution in original post

4 Replies 4

Sergiu.Daniluk
VIP Alumni
VIP Alumni

Hi @Esmogyi 

You don't need the json.dump().

You simply use the dictionary object.

 

objectJson = {
"TABLE_cdp_neighbor_detail_info": { "ROW_cdp_neighbor_detail_info": [ {...} ] }
} for neighbor in objectJson['TABLE_cdp_neighbor_detail_info']['ROW_cdp_neighbor_detail_info']: print(neighbor) {'ifindex': '824352435', 'device_id': 'mynexuscore-2', 'sysname': 'dc-core2', 'numaddr': '1', 'v4addr': '10.128.1.5', 'platform_id': 'N9K-C9372PX', 'capability': ['router', 'switch', 'Supports-STP-Dispute'], 'intf_id': 'mgmt0', 'port_id': 'mgmt0', 'ttl': '156', 'version': 'Cisco Nexus Operating System (NX-OS) Software, Version 7.0(3)I4(8a)', 'version_no': 'v2', 'duplexmode': 'full', 'mtu': '1500', 'syslocation': 'snmplocation', 'num_mgmtaddr': '1', 'v4mgmtaddr': '10.128.1.5'} {'ifindex': '436207616', 'device_id': 'tracer-01', 'numaddr': '2', 'v4addr': ['192.168.254.50', '192.168.5.50'], 'platform_id': 'N3000', 'capability': 'router', 'intf_id': 'Ethernet1/1', 'port_id': 'Te3/0/1', 'ttl': '153', 'version': '6.5.2.5', 'version_no': 'v2', 'nativevlan': '250', 'mtu': '0', 'num_mgmtaddr': '0'} {'ifindex': '4362246246', 'device_id': 'mynexuscore-2Standby', 'numaddr': '2', 'v4addr': '10.128.1.15', 'v6addr': 'fe80::5a97:bdff:bbbb:aaaa', 'platform_id': 'AIR-CT5520-K9', 'capability': 'host', 'intf_id': 'Ethernet1/3', 'port_id': 'TenGigabitEthernet0/0/1', 'ttl': '125', 'version': "Manufacturer's Name: Cisco Systems Inc. Product Name: Cisco Controller Product Version: 8.5.171.0 RTOS Version: 8.5.171.0 Bootloader Version: 8.1.102.0 Build Type: DATA + WPS", 'version_no': 'v2', 'duplexmode': 'full', 'mtu': '0', 'num_mgmtaddr': '0'} {'ifindex': '436209152', 'device_id': 'WLC-1', 'numaddr': '2', 'v4addr': '10.128.1.16', 'v6addr': 'fe80::72e4:22ff:bbbb:aaaa', 'platform_id': 'AIR-CT5520-K9', 'capability': 'host', 'intf_id': 'Ethernet1/4', 'port_id': 'TenGigabitEthernet0/0/1', 'ttl': '158', 'version': "Manufacturer's Name: Cisco Systems Inc. Product Name: Cisco Controller Product Version:8.5.171.0 RTOS Version: 8.5.171.0 Bootloader Version: 8.1.102.0 Build Type: DATA + WPS", 'version_no': 'v2', 'duplexmode': 'full', 'mtu': '0', 'num_mgmtaddr': '0'} {'ifindex': '436205555', 'device_id': 'MDF-1', 'vtpname': 'thisguy', 'numaddr': '1', 'v4addr': '10.128.1.18', 'platform_id': 'cisco WS-C2960X-48FPD-L', 'capability': ['switch', 'IGMP_cnd_filtering'], 'intf_id': 'Ethernet1/5', 'port_id': 'TenGigabitEthernet1/0/1', 'ttl': '165', 'version': 'Cisco IOS Software, C2960X Software (C2960X-UNIVERSALK9-M), Version 15.2(2)E3, RELEASE SOFTWARE (fc3)\nTechnical Support: http://www.cisco.com/techsupport\nCopyright (c) 1986-2015 by Cisco Systems, Inc.\nCompiled Wed 26-Aug-15 07:12 by prod_rel_team', 'version_no': 'v2', 'nativevlan': '1', 'duplexmode': 'full', 'mtu': '0', 'num_mgmtaddr': '1', 'v4mgmtaddr': '10.128.1.13'}

 

I printed the full neighbor details, but you can access/print any other key inside the entry.

 

Stay safe,

Sergiu

 

  1. I guess what I'm not understanding is what kind of format is this: list, tuple, dict?
  2. Why would the nexus output a TABLE and ROW detail info? 
  3. How do I iterate through this with a loop? 

 

playing around this code and trying to use objectJson.items()["TABLE.."]["ROW.."]: , flopping around parameters, i've gotten several different errors but not a single value of a device_id

 

for key, value in objectJson['TABLE_cdp_neighbor_detail_info']['ROW_cdp_neighbor_detail_info']:
    if key == "device_id":
        print(str(value))

 errors:

  1. for key, value in objectJson['TABLE_cdp_neighbor_detail_info']['ROW_cdp_neighbor_detail_info']:
    ValueError: too many values to unpack (expected 2)
  2. for key, value in objectJson.items(['TABLE_cdp_neighbor_detail_info']['ROW_cdp_neighbor_detail_info']):
    TypeError: list indices must be integers or slices, not str
  3. for key, value in objectJson['TABLE_cdp_neighbor_detail_info']['ROW_cdp_neighbor_detail_info']:
    ValueError: too many values to unpack (expected 2)

HI @Esmogyi 

Your outermost object is a dictionary and then within those top level key/value pairs you have strings and lists of dictionaries. 

Wrapping your head around these complex data structures made my head hurt but once you get it its amazing what you can do.

 

Not sure if this will help:
https://gratuitous-arp.net/decomposing-complex-json-data-structures/

 

One tip is to start at the top level and sort of peel the layers back.  I know from the first character "{" that I have a dictionary 

You can break out key/value pairs but a good shortcut with some of these complex structures is to look at the keys.

>>> print(objectJson.keys())
dict_keys(['TABLE_cdp_neighbor_detail_info'])
>>>

This is a dictionary with on key so I know the good stuff is at least one level deep.

 

Key/value break out if you have more than one key can be helpful.  Notice I want the key and then what type of object it has for a value.

>>> for key, value in objectJson.items():
...   print(f"key: {key} \t val: {type(value)}")
...
key: TABLE_cdp_neighbor_detail_info 	 val: <class 'dict'>
>>>

going to the next level:

>>> for key, value in objectJson['TABLE_cdp_neighbor_detail_info'].items():
...   print(f"key: {key} \t val: {type(value)}")
...
key: ROW_cdp_neighbor_detail_info 	 val: <class 'list'>

OK..now I have one more key and then I probably have the stuff I care about.

 

I now know that this structure is a list.  

objectJson['TABLE_cdp_neighbor_detail_info']['ROW_cdp_neighbor_detail_info']

Lets see how many rows we have:

 

print(len(objectJson['TABLE_cdp_neighbor_detail_info']['ROW_cdp_neighbor_detail_info']))
5

Sometimes its easier to put that long thing that is a list into a new variable as you can see below I put into "results_list" and then I iterate over results list.

 

>>> results_list = objectJson['TABLE_cdp_neighbor_detail_info']['ROW_cdp_neighbor_detail_info']
>>> for row in results_list: ... print(row) ... print() ... {'ifindex': '824352435', 'device_id': 'mynexuscore-2', 'sysname': 'dc-core2', 'numaddr': '1', 'v4addr': '10.128.1.5', 'platform_id': 'N9K-C9372PX', 'capability': ['router', 'switch', 'Supports-STP-Dispute'], 'intf_id': 'mgmt0', 'port_id': 'mgmt0', 'ttl': '156', 'version': 'Cisco Nexus Operating System (NX-OS) Software, Version 7.0(3)I4(8a)', 'version_no': 'v2', 'duplexmode': 'full', 'mtu': '1500', 'syslocation': 'snmplocation', 'num_mgmtaddr': '1', 'v4mgmtaddr': '10.128.1.5'} {'ifindex': '436207616', 'device_id': 'tracer-01', 'numaddr': '2', 'v4addr': ['192.168.254.50', '192.168.5.50'], 'platform_id': 'N3000', 'capability': 'router', 'intf_id': 'Ethernet1/1', 'port_id': 'Te3/0/1', 'ttl': '153', 'version': '6.5.2.5', 'version_no': 'v2', 'nativevlan': '250', 'mtu': '0', 'num_mgmtaddr': '0'} {'ifindex': '4362246246', 'device_id': 'mynexuscore-2Standby', 'numaddr': '2', 'v4addr': '10.128.1.15', 'v6addr': 'fe80::5a97:bdff:bbbb:aaaa', 'platform_id': 'AIR-CT5520-K9', 'capability': 'host', 'intf_id': 'Ethernet1/3', 'port_id': 'TenGigabitEthernet0/0/1', 'ttl': '125', 'version': "Manufacturer's Name: Cisco Systems Inc. Product Name: Cisco Controller Product Version: 8.5.171.0 RTOS Version: 8.5.171.0 Bootloader Version: 8.1.102.0 Build Type: DATA + WPS", 'version_no': 'v2', 'duplexmode': 'full', 'mtu': '0', 'num_mgmtaddr': '0'} {'ifindex': '436209152', 'device_id': 'WLC-1', 'numaddr': '2', 'v4addr': '10.128.1.16', 'v6addr': 'fe80::72e4:22ff:bbbb:aaaa', 'platform_id': 'AIR-CT5520-K9', 'capability': 'host', 'intf_id': 'Ethernet1/4', 'port_id': 'TenGigabitEthernet0/0/1', 'ttl': '158', 'version': "Manufacturer's Name: Cisco Systems Inc. Product Name: Cisco Controller Product Version:8.5.171.0 RTOS Version: 8.5.171.0 Bootloader Version: 8.1.102.0 Build Type: DATA + WPS", 'version_no': 'v2', 'duplexmode': 'full', 'mtu': '0', 'num_mgmtaddr': '0'} {'ifindex': '436205555', 'device_id': 'MDF-1', 'vtpname': 'thisguy', 'numaddr': '1', 'v4addr': '10.128.1.18', 'platform_id': 'cisco WS-C2960X-48FPD-L', 'capability': ['switch', 'IGMP_cnd_filtering'], 'intf_id': 'Ethernet1/5', 'port_id': 'TenGigabitEthernet1/0/1', 'ttl': '165', 'version': 'Cisco IOS Software, C2960X Software (C2960X-UNIVERSALK9-M), Version 15.2(2)E3, RELEASE SOFTWARE (fc3)\nTechnical Support: http://www.cisco.com/techsupport\nCopyright (c) 1986-2015 by Cisco Systems, Inc.\nCompiled Wed 26-Aug-15 07:12 by prod_rel_team', 'version_no': 'v2', 'nativevlan': '1', 'duplexmode': 'full', 'mtu': '0', 'num_mgmtaddr': '1', 'v4mgmtaddr': '10.128.1.13'} >>>

Now you can see that each row in the list is a dictionary.  Well we know how to process that now.

Lest look at the keys we have available to us

 

>>> for row in results_list:
...   print(row.keys())
...
dict_keys(['ifindex', 'device_id', 'sysname', 'numaddr', 'v4addr', 'platform_id', 'capability', 'intf_id', 'port_id', 'ttl', 'version', 'version_no', 'duplexmode', 'mtu', 'syslocation', 'num_mgmtaddr', 'v4mgmtaddr'])
dict_keys(['ifindex', 'device_id', 'numaddr', 'v4addr', 'platform_id', 'capability', 'intf_id', 'port_id', 'ttl', 'version', 'version_no', 'nativevlan', 'mtu', 'num_mgmtaddr'])
dict_keys(['ifindex', 'device_id', 'numaddr', 'v4addr', 'v6addr', 'platform_id', 'capability', 'intf_id', 'port_id', 'ttl', 'version', 'version_no', 'duplexmode', 'mtu', 'num_mgmtaddr'])
dict_keys(['ifindex', 'device_id', 'numaddr', 'v4addr', 'v6addr', 'platform_id', 'capability', 'intf_id', 'port_id', 'ttl', 'version', 'version_no', 'duplexmode', 'mtu', 'num_mgmtaddr'])
dict_keys(['ifindex', 'device_id', 'vtpname', 'numaddr', 'v4addr', 'platform_id', 'capability', 'intf_id', 'port_id', 'ttl', 'version', 'version_no', 'nativevlan', 'duplexmode', 'mtu', 'num_mgmtaddr', 'v4mgmtaddr'])
>>>

 OK lets say I want platform and v4IP:

>>> for row in results_list:
...   print(f"Platform: {row['platform_id']} IP: {row['v4addr']}")
...
Platform: N9K-C9372PX IP: 10.128.1.5
Platform: N3000 IP: ['192.168.254.50', '192.168.5.50']
Platform: AIR-CT5520-K9 IP: 10.128.1.15
Platform: AIR-CT5520-K9 IP: 10.128.1.16
Platform: cisco WS-C2960X-48FPD-L IP: 10.128.1.18
>>>

With all of this you can now see that some of the values are lists (devices with multiple IPs) so one more step to iterate over those if you need to.

 

Spend some time working through these exercises yourself.  Knowing how to deal with these complex structures will serve you well!



errors:

  1. for key, value in objectJson['TABLE_cdp_neighbor_detail_info']['ROW_cdp_neighbor_detail_info']:
    ValueError: too many values to unpack (expected 2)

    Here you are trying to treat a list like a dictionary, hence the "too many values to unpack" error.  Normally when I get this error I've forgotten to use  .items() in my for statement.

  2. for key, value in objectJson.items(['TABLE_cdp_neighbor_detail_info']['ROW_cdp_neighbor_detail_info']):
    TypeError: list indices must be integers or slices, not str

    I don't believe you can pass the .items() iterator an argument. Normally the use is:
    for key, val in dict_object.items()
    that "unpacks" the key value pair and puts the key in they "key" variable and whatever the value is in the "val" variable.    
    the error tells you that you are basically not treating a list as a list.

 

  1. for key, value in objectJson['TABLE_cdp_neighbor_detail_info']['ROW_cdp_neighbor_detail_info']:
    ValueError: too many values to unpack (expected 2)

this is like the first example.

Thanks. I havent ran through any complex data before. I've been relearning python due to the DevNet Associate and the OCG does not touch upon anything more than the basics. However, I did find the online DevNet learning labs does go into a little detail about nested data.

https://developer.cisco.com/learning/modules/intro-python/parsing-json-python/step/4

Between your post and this DevNet module, I think I may be able to achieve what I'm looking to do. Its taking quite a bit longer than I had hope for, but hopefully I run into more projects like this in the future and I can make use of this skill. Thanks!