Hunter Hunter - 7 months ago 5
Python Question

Python: I don't understand the order of a function calling a function

I'm following the book Data Science from Scratch by Joel Grus and they decribe the following code to create an identity matrix

def make_matrix(num_rows, num_cols, entry_fn):
return [[entry_fn(i, j)
for j in range(num_cols)]
for i in range(num_rows)]

def is_diagonal(i, j):
return 1 if i == j else 0

identity_matrix = make_matrix(5, 5, is_diagonal)


Although I can sort of see how this create an identity matrix, I'm having difficulties exactly understanding it.

The way I see it is that we call the function
make_matrix
with arguments
5
,
5
and
is_diagonal
. At that point the code will thus go to the
is_diagonal(i, j) for j in range(5)
and so it will go to the function
is_diagonal
without having seen the outer loop
... for i in range(5)
. But if this is true, then it seems that the function
is_diagonal
will get as input variable
(0,j)
,
(1,j)
, ...,
(4,j)
and so
is_diagonal
doesn't get enough input variables (because
j
isn't defined). Could someone please explain where I'm going wrong in my train of thoughts?

Answer

That type of expression is almost best of thought of in a Yoda sense: backwards it is. The last part of the expression is evaluated before the first.

This function is the equivalent of:

def make_matrix(num_rows, num_cols, entry_fn):
    ret = [] # you are dealing with an outer list 
    # and an outer loop
    for i in range(num_rows):
        cur = [] # and an inner list
        # And an inner loop
        for j in range(num_cols):
            curr.append(entry_fn(i,j)) # you add the result to the inner list
        # and once you're done with the inner loop, and the result to the outer list
        ret.append(cur) 
    # finally, complete the outer loop and return the result
    return ret

Both i AND j exist in the greater context of the function, even though i is defined after j in the more compressed version.

Comments