Chapter 10. Nested data structures

Table of Contents

10.1. Nested data structures
10.2. Identity of objects
10.3. Copying complex data structures
10.4. Modifying nested structures

10.1. Nested data structures

Composed data structures, such as lists, dictionaries and tuples can be nested in Python. This means that you can use these data structures as elements of themselves.

>>> l = [1, [2, 3, [4]], [5, 6]]
  

The list above contains 3 elements.

>>> len(l)
3
  

The first element is the integer 1, whereas the second and third element are lists themselves.

>>> l[0]
1
>>> l[1]
[2, 3, [4]]
>>> l[2]
[5, 6]
  

Figure 10.1 shows a representation of this list. Each element of a list is represented by a box containing a pointer to the value of the element. Like pointers in a namespace representation, these pointers are references. Remember that a reference is an address to a memory location (Section 2.4).

Figure 10.1. Representation of nested lists

As far we have said that a list is an ordered collection of objects. But they do not really contain these objects. They rather contain references to them.

How can we access to the elements of the internal list?  Figure 10.1 makes clear there are different levels of the nested structure. Each time we follow a reference we go to the next level of the structure.

To access the value 2 of our example list, we could store the value of the second element in a variable which creates the new reference l1 to this sublist. And then ask for the first element of l1.

>>> l1 = l[1]
>>> l1
[2, 3, [4]]
>>> l1[0]
2
  

But we can also follow the references directly without creating a new variable.

>>> l[1][0]
2
  

Figure 10.2 colors the path of the references we have followed to access the value 2.

Figure 10.2. Accessing elements in nested lists

Nested dictionaries.  Dictionaries can be nested in the same way as lists. Here is an example of a dictionary that stores restriction enzyme data.

>>> enzdict = { 'EcoRI': {'pattern': 'GAATTC', 'cut_position': '1'}, 
      'BamHI': {'pattern': 'GGATCC', 'cut_position': '1'}}
>>> enzdict
{ 'EcoRI': {'pattern': 'GAATTC', 'cut_position': '1'}, 
  'BamHI': {'pattern': 'GGATCC', 'cut_position': '1'}}

>>> enzdict['EcoRI']['pattern']
'GAATTC'
      
Figure 10.3 shows a representation of enzdict.

Figure 10.3. Representation of a nested dictionary

Mixed structures. In the same way as above you can construct mixed structures. Here is an example of a restriction enzyme dictionary that stores, in addition to the pattern, all occurrences of the pattern in a sequence stored in lists.

Example 10.1. A mixed nested datastructure

>>>  enzdict = { 'EcoRI': {'pattern': 'GAATTC', 'occ': [0, 109, 601]},
                  'BamHI': {'pattern': 'GGATCC', 'occ': [31, 59]}
      

Exercise 10.1. Representing complex structures

Try to draw a representation of the the mixed structure in Example 10.1.