2016-04-21 48 views
0

我下面由Joel丹頂鶴書數據科學從頭開始的順序,他們描繪這一下面的代碼創建單位矩陣的Python:我不明白一個函數的調用函數

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) 

雖然我可以看到這是如何創建一個身份矩陣,我很難理解它。

我看到它的方式是我們調用函數make_matrix,其參數爲5,5is_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未定義)。有人能解釋我的思路中哪裏出錯嗎?

+0

想一想爲什麼'entry_fn(i,j)'在Python到達'範圍內(num_cols)''之前沒有被調用。同樣的邏輯也適用於爲什麼在Python得到'for range in(num_rows)'之前,內部列表理解沒有得到評估。 – user2357112

+0

@ user2357112我不確定我明白你的意思。由於cwallenpoole的回答,我現在看到它的方式是在「內部」綜合列表之前評估「外部」綜合列表(即表達式的最後部分),這實際上解釋了爲什麼「entry_fn(i, j)'在Python到達範圍內('num_cols)''之前不會調用''。你這句話的方式好像我的邏輯倒退了? – Hunter

+1

你的邏輯似乎是正確的;有幾個地方我不能說出你的想法是否有錯,或者你只是使用了錯誤的單詞。儘管如此,嘗試糾正「評估」的用法可能會比有用的更困惑。但我會說,「綜合清單」不是一個實際的術語,正確的術語是「列表理解」,它指的是從左括號到右括號的所有內容,而不僅僅是從'for'開始的部分。 – user2357112

回答

3

表達式(a comprehension)的這種類型在Yoda意義上幾乎是最好的想法:倒退了。表達式的最後部分在第一部分之前進行評估。

此功能相當於:

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 

兩個ij存在於功能的更大的背景下,即使是i在更加壓縮的版本j後確定。

+0

我認爲如果您至少提到這是一個列表理解並提供了一個鏈接,而不是簡單地擴展它,那麼這個答案可以得到改進 – Natecat

+0

謝謝您的明確答案!可以肯定的是,每當我們在另一個綜合列表中有一個全面的列表時,「外部」綜合列表(即表達式的最後部分)總是**在「內部」綜合列表之前被評估?或者這是一個特例? – Hunter

+0

我喜歡Yoda的比較......讓愛好程序員理解它。 – 2016-04-23 01:30:42