Hunter Hunter - 6 months ago 3x
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
with arguments
. 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
without having seen the outer loop
... for i in range(5)
. But if this is true, then it seems that the function
will get as input variable
, ...,
and so
doesn't get enough input variables (because
isn't defined). Could someone please explain where I'm going wrong in my train of thoughts?


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
    # 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.