Hunter - 11 months ago 24

Python Question

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`

`5`

`5`

`is_diagonal`

`is_diagonal(i, j) for j in range(5)`

`is_diagonal`

`... for i in range(5)`

`is_diagonal`

`(0,j)`

`(1,j)`

`(4,j)`

`is_diagonal`

`j`

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.