2016-09-30 42 views
2

我在學習列表推導,並且通過切換變量得到2個不同的結果,儘管它們看起來應該是一樣的。當在列表理解中對語句重新排序時NameError

陣列a等於[[0, 0, 0, 0, 0], [1, 0, 0, 0, 0], [0, 0, 0, 0, 0], [0, 0, 0, 0, 0], [0, 0, 0, 0, 0]]

列表綜合1部作品:

[(i,j) for j in range(len(a[i])) for i in range(len(a))] 

返回:

[(0, 0), (1, 0), (2, 0), (3, 0), (4, 0), (0, 1), (1, 1), (2, 1), (3, 1), (4, 1), (0, 2), (1, 2), (2, 2), (3, 2), (4, 2), (0, 3), (1, 3), (2, 3), (3, 3), (4, 3), (0, 4), (1, 4), (2, 4), (3, 4), (4, 4)] 

正如所預期的。

但翻轉變量...

[(j,i) for i in range(len(a[j])) for j in range(len(a))] 

導致NameError:沒有定義

名「J」可有人請向我解釋爲什麼它的事項i或j是否是第一位的?

回答

4

這並不是說這裏重要的變量的順序。事實上,出於與列表理解2相同的原因,運行列表理解1也是行不通的。我猜你在程序的前面定義了i,這就是爲什麼列表理解1適合你。問題是for循環的順序。

我會嘗試通過示例來解釋。如果你這樣寫,它會運行良好:

[ [(i,j) for j in range(len(a[i]))] for i in range(len(a))] 

請注意我添加的方括號。在這種情況下,for迴路與i首先發生,然後forj迴路。 (但應該指出,這將返回元組列表的列表。)或者,這也將運行良好:

[(i,j) for i in range(len(a)) for j in range(len(a[i]))] 

當兩個for環路寫在一起的方式(沒有多餘的括號這個時候),他們正在讀左到右。

+0

你應該提到你的第一個例子,嵌套列表comp,創建了元組列表的列表。或者只是將它的輸出包含在你的答案中。 –

+1

好的是有道理的,所以在第一個例子中,括號後面的for循環是第一個運行的嗎?例如,如果'ninecells = [[a [0] [0] + w,a [0] [1] + h]在範圍(-1,2)中對於範圍(-1,2)中的w, '那麼'範圍內的h'將首先運行? – st4rgut

+0

@ PM2Ring好點,補充說。 – Meerness

6

如果在單個列表理解中有一個雙重for循環,則它等同於使用「傳統」for循環以相同順序執行那些for循環。所以

result = [(j,i) for i in range(len(a[j])) for j in range(len(a))] 

是(幾乎完全)等同於

result = [] 
for i in range(len(a[j])): 
    for j in range(len(a)): 
     result.append((j, i)) 

正如你所看到的,當你做len(a[j])變量j不存在,這就是爲什麼你會得到NameError

順便說一句,你的第一個列表比較不應該工作。我懷疑你的代碼早些時候定義了i,這就是爲什麼你沒有得到NameError。下面是該列表組件的一個稍微改進的版本,它假定a是一個矩陣,即它的所有子列表都是相同的長度,並且它至少包含一個子列表。

[(i,j) for j in range(len(a[0])) for i in range(len(a))] 

我們也可以做

[(j, i) for i in range(len(a)) for j in range(len(a[0]))] 

的這兩項列表譜曲創建此列表:

[(0, 0), (1, 0), (2, 0), (3, 0), (4, 0), (0, 1), (1, 1), (2, 1), (3, 1), (4, 1), (0, 2), (1, 2), (2, 2), (3, 2), (4, 2), (0, 3), (1, 3), (2, 3), (3, 3), (4, 3), (0, 4), (1, 4), (2, 4), (3, 4), (4, 4)] 
+0

注意:既不listcap應該工作,我懷疑全局或嵌套範圍雖然定義了一個名爲'i'的變量,並且由於矩陣是'nxn',只要'i'是一個合法的索引,它的用途(計算「範圍」的長度)即使它沒有按正確的順序工作。 – ShadowRanger

+0

@ShadowRanger:是的,我只是注意到了我自己。 :)我會在我的答案中提到這一點。 –