Accessing data in nested Python lists and dicts

Andreas Baekdahl

When working with JSON based REST APIs, it is common to receive responses with nested data structures in various combinations.

After converting JSON to a Python data structure we can easily iterate through it thanks to the built-in flexibility of the for-loop in Python, or they can be accessed directly with list indices or key references.

The following examples serve as a basic reference to working with nested data structures using lists and dictionaries.

In the examples below you can see various methods on accessing data with the following nested formats:

  • list
  • dict
  • list of lists
  • list of dicts
  • dict of lists
  • dict of dicts

With each of those data structures you will see how to:

  • loop through keys and/or values
  • reference elements directly without looping
  • extract subsections of a list
  • simple error handling for invalid dict key

Not all of the examples are perfect for every situation, so it's up to you to evaluate what method makes most sense in your case.

 

Loop through a list, or access an item directly


network_fundamentals_list = [
  "vlan",
  "mac-address",
  "vrf",
  "ip-address"
]

for network_concept in network_fundamentals_list:
  print(network_concept)
## Output:
# vlan
# mac-address
# vrf
# ip-address


# 4 ways of direct access. Pick the most simplest one suitable for your use-case:

print(network_fundamentals_list[2])
print(network_fundamentals_list[-1])
print(network_fundamentals_list[1:2])
print(network_fundamentals_list[2:])
## Output:
# vrf
# ip-address
# ['mac-address']
# ['vrf', 'ip-address']

Loop through dictionary keys, values or both (items), or access an item directly


network_fundamentals_dict = {
  "vlan": "broadcast domain",
  "mac-address": "physical address",
  "vrf": "routing instance",
  "ip-address": "logical address"
}

for network_concept in network_fundamentals_dict.keys():
  print(network_concept)
## Output:
# vlan
# mac-address
# vrf
# ip-address


for description in network_fundamentals_dict.values():
  print(description)
## Output:
# broadcast domain
# physical address
# routing instance
# logical address


for network_concept, description in network_fundamentals_dict.items():
  print(network_concept + " is a " + description)
## Output:
# vlan is a broadcast domain
# mac-address is a physical address
# vrf is a routing instance
# ip-address is a logical address


# 4 ways of direct access. Pick the most simplest one suitable for your use-case:
print(network_fundamentals_dict["vlan"])
print(network_fundamentals_dict.get("ipv6-anycast", "NO SUCH ELEMENT!"))
print(list(network_fundamentals_dict.values())[1])
print(list(network_fundamentals_dict.keys())[2])
## Output:
# broadcast domain
# NO SUCH ELEMENT!
# physical address
# vrf

Loop through a list of lists, or access an item directly


network_fundamentals_outer_list = [
  [
    "vlan",
    "mac-address"
  ],
  [
    "vrf",
    "ip-address"
  ]
]

for network_fundamentals_inner_list in network_fundamentals_outer_list:
  for network_concept in network_fundamentals_inner_list:
    print(network_concept)
## Output:
# vlan
# mac-address
# vrf
# ip-address


# 4 ways of direct access. Pick the most simplest one suitable for your use-case:
print(network_fundamentals_outer_list[0][0])
print(network_fundamentals_outer_list[0][1])
print(network_fundamentals_outer_list[1])
print(network_fundamentals_outer_list[-1][-1])
## Output:
# vlan
# mac-address
# ['vrf', 'ip-address']
# ip-address

Loop through a list of dictionary keys, values or both (items), or access an item directly


network_fundamentals_list_of_dicts = [
  {
    "vlan": "broadcast domain",
    "mac-address": "physical address"
  },
  {
    "vrf": "routing instance",
    "ip-address": "logical address"
  }
]

for network_fundamentals_inner_dict in network_fundamentals_list_of_dicts:
  for network_concept in network_fundamentals_inner_dict.keys():
    print(network_concept)
## Output:
# vlan
# mac-address
# vrf
# ip-address

for network_fundamentals_inner_dict in network_fundamentals_list_of_dicts:
  for description in network_fundamentals_inner_dict.values():
    print(description)
## Output:
# broadcast domain
# physical address
# routing instance
# logical address

for network_fundamentals_inner_dict in network_fundamentals_list_of_dicts:
  for network_concept, description in network_fundamentals_inner_dict.items():
    print(network_concept + " is a " + description)
## Output:
# vlan is a broadcast domain
# mac-address is a physical address
# vrf is a routing instance
# ip-address is a logical address


# 4 ways of direct access. Pick the simplest one suitable for your use-case:
print(network_fundamentals_list_of_dicts[0]["vlan"])
print(list(network_fundamentals_list_of_dicts[0].values())[1])
print(list(network_fundamentals_list_of_dicts[1].keys())[0])
print(network_fundamentals_list_of_dicts[-1]["ip-address"])
## Output:
# broadcast domain
# physical address
# vrf
# logical address

Loop through a dictionary of lists, or access an item directly


network_fundamentals_outer_dict = {
  "layer-2": [
    "vlan",
    "mac-address"
  ],
  "layer-3": [
    "vrf",
    "ip-address"
  ]
}

for osi_model_layer, network_fundamentals_inner_list in network_fundamentals_outer_dict.items():
  for network_concept in network_fundamentals_inner_list:
    print(network_concept + " belongs to ISO model " + osi_model_layer)
## Output:
# vlan belongs to ISO model layer-2
# mac-address belongs to ISO model layer-2
# vrf belongs to ISO model layer-3
# ip-address belongs to ISO model layer-3


# 4 ways of direct access. Pick the simplest one suitable for your use-case:
print(network_fundamentals_outer_dict["layer-2"][0])
print(network_fundamentals_outer_dict["layer-3"][-1])
print(list(network_fundamentals_outer_dict.values())[0][1])
print(list(network_fundamentals_outer_dict.keys())[1])
## Output:
# vlan
# ip-address
# mac-address
# layer-3

Loop through a dictionary of dictionaries, or access an item directly


network_fundamentals_outer_dict = {
  "layer-2": {
    "vlan": "broadcast domain",
    "mac-address": "physical address"
  },
  "layer-3": {
    "vrf": "routing instance",
    "ip-address": "logical address"
  }
}

for osi_model_layer, network_fundamentals_inner_dict in network_fundamentals_outer_dict.items():
  for network_concept, description in network_fundamentals_inner_dict.items():
    print(network_concept + " is a " + description + " and belongs to ISO model " + osi_model_layer)
## Output:
# vlan is a broadcast domain and belongs to ISO model layer-2
# mac-address is a physical address and belongs to ISO model layer-2
# vrf is a routing instance and belongs to ISO model layer-3
# ip-address is a logical address and belongs to ISO model layer-3


# 4 ways of direct access. Pick the simplest one suitable for your use-case:
print(network_fundamentals_outer_dict["layer-2"]["mac-address"])
print(list(network_fundamentals_outer_dict.values())[0]["vlan"])
print(list(network_fundamentals_outer_dict["layer-3"].keys())[0])
print(list(network_fundamentals_outer_dict.keys())[1])
## Output:
# physical address
# broadcast domain
# vrf
# layer-3

Back to blog

Leave a comment

Please note, comments need to be approved before they are published.