2013-08-07 115 views
1

我預計以下2個代碼段基本上是等效的。爲什麼嵌套列表索引與列表解析交換?

return tuple(tuple(False if (i,j) in neighborhood else avail[i][j] 
    for i in range(len(avail)))  
    for j in range(len(avail[i]))) 

(False, False, True, True, True) 
(False, False, True, True, True) 
(False, False, True, True, True) 
(False, False, True, True, True) 
(True, True, True, True, True) 

ls = [[val for val in row] for row in avail] 
for i in range(len(avail)): 
    for j in range(len(avail[i])): 
     if (i,j) in neighborhood: 
      ls[i][j] = False 
return ls 

[False, False, False, False, True] 
[False, False, False, False, True] 
[True, True, True, True, True] 
[True, True, True, True, True] 
[True, True, True, True, True] 

帶for-loops的那個是「正確的」(那就是我想要的)。爲什麼列表理解版本交換索引?

+0

請忽略列表元組差異 – user1358

回答

1

你的循環在第一個版本中倒置。你正在創建循環超過range(len(avail))的內部元組和循環超過range(len(avail[i]))的外部元組。

你的代碼是這樣而不是當量(以列表而不是元組):

outer = [] 
for j in range(len(avail[i])): 
    inner = [] 
    for i in range(len(avail)): 
     inner.append(False if (i,j) in neighborhood else avail[i][j]) 
    outer.append(inner) 

,並依靠i仍被指定爲全局。你也能看到這個當您根據括號縮進你的表達:

return tuple(
    tuple(
     False if (i,j) in neighborhood else avail[i][j] 
     for i in range(len(avail)) 
    )  
    for j in range(len(avail[i])) 
) 

反向環路(縮進不同通信的分組越好):

return tuple(
    tuple(False if (i,j) in neighborhood else avail[i][j] for j in range(len(avail[i])))  
    for i in range(len(avail))) 

以上是等價的:

outer = [] 
for i in range(len(avail)): 
    inner = [] 
    for j in range(len(avail[i])): 
     inner.append(False if (i,j) in neighborhood else avail[i][j]) 
    outer.append(inner) 

您可以使用enumerate()簡化代碼:

return tuple(
    tuple(False if (i,j) in neighborhood else v for j, v in enumerate(row))  
    for i, row in enumerate(avail)) 
+0

但如果我交換它們,我會得到「UnboundLocalError:本地變量」i「在賦值之前引用」爲什麼? – user1358

+0

你應該*已經*得到那個錯誤。 –