List, matrix, array (length of a list, nested list as a higher dimension matrix/array)


The len() function only counts the top level elements and will not dig into list elements that are lists themselves:

M = [ 
   ["0/0", "0/1"],
   ["1/0", "1/1"], 
   ["2/0", "2/1"] 
]

len(M)   => 3

M is nominally a matrix with two dimensions (also called rank 2), the 1. dimension contains 3 of what I would call the top level elements [ <> , <>  , <> ] . These 3 dimension 1 elements can be accessed by appending one [] index, i.e. M[0]  has one of the [], and returns the list ["0/0", "0/1"].  Counting the total number of strings in M can be done via a loop through the top level list:

total_len = 0
for e in M: total_len = total_len + len(e)
print total_len, "words in M"

In my 2D matrix M, each element in turn contains a list, so each dimension 1 element expands into several words (dimension 2 elements). In the traditional spreadsheet view, M would look like this:

      A       B     ...
1  "0/0" "0/1"
2  "1/0" "1/1"
3  "2/0" "2/1"
...

Accessing the list elements inside this list is done by a second [] index: M[0][1] returns "0/1".
Note that the understanding here is that the first index denotes the row number (what I show as 1,2,3, ...) and the second index denotes the column (what I show as A, B, C, ...), so M[2][1] means: go to the  3. row (python index 2) and in that row find the 2. column (python index 1), and grab that value, i.e. "2/1"

As Tyrone pointed out, as the list values here are strings, you can dig even deeper and get a letter from the string by using a third index:  M[2][1][2] gets the letter with index 2 of the string "2/1" i.e. "1". You could think of these letter as dimension 3 elements, so M is really a 3D array. How about counting the number of letters in M? We simply loop through a loop:

total_len = 0
for dim1_element in M:
    print dim1_element
    for dim2_element in dim1_element:
        print " ", dim2_element, "has", len(dim2_element), "letters"
        total_len = total_len + len(dim2_element)
print total_len, "letters in M"

so we have a total of 2 by by 3 by  3 = 18 dimension 3 elements (letters) here. Note that this sort of list traversal also works for a "matrix" that's actually not "regular" as the 2 by 3 by 3 matrix M! 

weirdM = [ ["0/0", "0/1"], ["1/0", "really_long", ""], [] ] 

Here we have 3 top level elements but these do not contain the same number of elements, one of them (index 2) is an empty list and [1][2] is an empty string. Still it reports the total number of letters (20). 
Bottom line: traversing a nested list with nested for loops is easy as long as you know how many dimensions the nested list has.

For those looking for the more traditional (regular) matrix representations for numeric values, the numpy module (which you can install from here), offers the array class:

import numpy
a = numpy.array([ [0,  1,  2,  3], [4,  5,  6,  7],[8,  9, 10, 11] ])
print a

[[ 0  1  2  3]
 [ 4  5  6  7]
 [ 8  9 10 11]]

No comments:

Search This Blog