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)
is_diagonal(i, j) for j in range(5)
... for i in range(5)
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
j exist in the greater context of the function, even though
i is defined after
j in the more compressed version.