Skip to content

A Comprehensive Guide to Iterating Through and Manipulating Nested Data Structures in Python

Updated: at 02:50 AM

Nested data structures are common in Python programming and allow you to store collections of data within other collections. For example, a list can contain other lists as elements, a dictionary can hold other dictionaries as values, etc. While powerful, nested structures can get complex, so iteratively traversing them and manipulating the nested data requires some special techniques in Python.

In this guide, we will provide a comprehensive overview of iterating through and programmatically manipulating nested data structures in Python. We will cover the core concepts, useful methods and functions, and include plenty of code examples and best practices.

Table of Contents

Open Table of Contents

Overview of Nested Data Structures

In Python, the most common nested structures are:

For example:

nested_list = [
  [1, 2, 3],
  [4, 5, 6],
  [7, 8, 9]
]

nested_dict = {
  'first': {
    'a': 1,
    'b': 2
  },
  'second': {
    'c': 3,
  }
}

nested_tuple = (
  (1, 2, 3),
  (4, 5, 6)
)

The nested levels can go arbitrarily deep, leading to multi-dimensional and potentially complex data structures.

When iterating and manipulating, we need to properly traverse each nested level and access the inner elements in the correct sequence.

Iterating Through Nested Structures

Iterating through nested structures requires recursively traversing each sub-level while tracking the parent-child relationship. Here are some ways to iterate nested containers:

Nested Lists

Use nested for loops to sequentially access each sub-list:

nested_list = [
  [1, 2, 3],
  [4, 5, 6],
  [7, 8, 9]
]

for sub_list in nested_list:
  for item in sub_list:
    print(item)

Or traverse using list comprehensions:

[item for sub_list in nested_list for item in sub_list]

Nested Dictionaries

Iterate through the .keys() first, then their associated values:

nested_dict = {
  'first': {
    'a': 1,
    'b': 2
  },
  'second': {
    'c': 3,
  }
}

for key1 in nested_dict:
  for key2 in nested_dict[key1]:
    print(nested_dict[key1][key2])

A dictionary comprehension offers a concise way too:

{value for key1 in nested_dict for key2, value in nested_dict[key1].items()}

Nested Tuples

Employ nested for loops like lists:

nested_tuple = (
  (1, 2, 3),
  (4, 5, 6)
)

for sub_tuple in nested_tuple:
  for item in sub_tuple:
    print(item)

Or a generator expression:

(item for sub_tuple in nested_tuple for item in sub_tuple)

Custom Classes

To traverse nested custom objects, use nested loops iterating over attributes:

class Node:
  def __init__(self, val, left=None, right=None):
    self.val = val
    self.left = left
    self.right = right

root = Node(1,
            Node(2, Node(4), Node(5)),
            Node(3, Node(6), Node(7)))

def traverse(node):
  print(node.val)
  if node.left:
    traverse(node.left)
  if node.right:
    traverse(node.right)

traverse(root)

This will recursively visit each node in the tree.

Manipulating Nested Structures

In addition to traversing nested data structures, we often need to manipulate them by adding, updating or deleting elements. Here are some tips for modifying nested data:

Modifying Nested Lists

Use index notation and slice assignment to modify specific sub-lists or elements:

nested_list[0] = ['a', 'b', 'c'] # replace first sub-list
nested_list[1][0] = 'z' # set specific element
nested_list[1][1:3] = [5, 5] # slice replace

You can also use list methods like append() and extend() on the sub-lists:

nested_list[2].append(10)

nested_list[0].extend([7, 8])

And insert new sub-lists with insert():

nested_list.insert(1, [10, 11, 12])

Modifying Nested Dictionaries

Modify values using their keys:

nested_dict['first']['c'] = 4 # add new key

nested_dict['second']['c'] = 10 # update value

Delete keys via pop():

nested_dict['first'].pop('a')

And add new inner dicts with:

nested_dict['third'] = {'d': 3}

Modifying Nested Tuples

Tuples are immutable, so you need to redefine entire sections instead of modifying directly:

nested_tuple = (
  (1, 2, 'a'),
  (4, 5, 6)
)

# Replace sub-tuple
nested_tuple = nested_tuple[:1] + (('b', 'c', 'd'),)

# Insert new sub-tuple
nested_tuple = nested_tuple + ((7, 8, 9),)

Modifying Nested Classes

Change object attributes and re-assign references to add, update or delete nested elements:

root.left.right = Node(8) # add node

root.right = None # delete node

root.val = 5 # update value

Best Practices

Follow these tips when working with nested data structures in Python:

Conclusion

This guide covered a variety of techniques and best practices for iterating through and programmatically manipulating nested data structures in Python. The key is understanding the recursive nature of nested traversal and properly tracking the parent-child relationships. Built-in functions like enumerate() and libraries like collections provide useful tools as well. Mastering nested iterations and modifications will allow you to work efficiently with complex multidimensional data in Python.